Replacing letters with numbers with its position in alphabetChange upper or lowercase vowels to [0,1,2,3,4] respectively and leave the rest the sameNumber Of Matching Elements In Two ListsTough List Comprehension Split Letters and NumbersPathname matching and listing programYet another lightweight Enum for Python 2.7Determine if two strings with unrecognized letters are from the same textDynamic programming solution for cross river algorithmApproximate string search in PythonPython, given a word, generate a list with one letter changing for each letter in alphabetTransform letters in a string
Opacity of an object in 2.8
What did Alexander Pope mean by "Expletives their feeble Aid do join"?
how to write formula in word in latex
A link redirect to http instead of https: how critical is it?
What options are left, if Britain cannot decide?
What approach do we need to follow for projects without a test environment?
How can I track script which gives me "command not found" right after the login?
Sailing the cryptic seas
What are substitutions for coconut in curry?
Does Mathematica reuse previous computations?
Min function accepting varying number of arguments in C++17
Instead of Universal Basic Income, why not Universal Basic NEEDS?
An inequality of matrix norm
Who is flying the vertibirds?
PTIJ: Who should I vote for? (21st Knesset Edition)
Why one should not leave fingerprints on bulbs and plugs?
How Could an Airship Be Repaired Mid-Flight
Python if-else code style for reduced code for rounding floats
If curse and magic is two sides of the same coin, why the former is forbidden?
how to draw discrete time diagram in tikz
How could a scammer know the apps on my phone / iTunes account?
Is a party consisting of only a bard, a cleric, and a warlock functional long-term?
Why is the President allowed to veto a cancellation of emergency powers?
Do I need to be arrogant to get ahead?
Replacing letters with numbers with its position in alphabet
Change upper or lowercase vowels to [0,1,2,3,4] respectively and leave the rest the sameNumber Of Matching Elements In Two ListsTough List Comprehension Split Letters and NumbersPathname matching and listing programYet another lightweight Enum for Python 2.7Determine if two strings with unrecognized letters are from the same textDynamic programming solution for cross river algorithmApproximate string search in PythonPython, given a word, generate a list with one letter changing for each letter in alphabetTransform letters in a string
$begingroup$
If anything in the text isn't a letter, ignore it and don't return it.
a
being1
,b
being2
, etc.
As an example:
alphabet_position("The sunset sets at twelve o' clock.")
Should return
"20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3
11" as a string.
It is my naive solution and my code is below in python 2.7
def alphabet_position(text):
dictt = 'a':'1','b':'2','c':'3','d':'4','e':'5','f':'6','g':'7','h':'8',
'i':'9','j':'10','k':'11','l':'12','m':'13','n':'14','o':'15','p':'16','q':'17',
'r':'18','s':'19','t':'20','u':'21','v':'22','w':'23','x':'24','y':'25','z':'26'
arr = []
new_text = text.lower()
for i in list(new_text):
for k, j in dictt.iteritems():
if k == i:
arr.append(j)
return ' '.join(arr)
python strings python-2.x
$endgroup$
add a comment |
$begingroup$
If anything in the text isn't a letter, ignore it and don't return it.
a
being1
,b
being2
, etc.
As an example:
alphabet_position("The sunset sets at twelve o' clock.")
Should return
"20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3
11" as a string.
It is my naive solution and my code is below in python 2.7
def alphabet_position(text):
dictt = 'a':'1','b':'2','c':'3','d':'4','e':'5','f':'6','g':'7','h':'8',
'i':'9','j':'10','k':'11','l':'12','m':'13','n':'14','o':'15','p':'16','q':'17',
'r':'18','s':'19','t':'20','u':'21','v':'22','w':'23','x':'24','y':'25','z':'26'
arr = []
new_text = text.lower()
for i in list(new_text):
for k, j in dictt.iteritems():
if k == i:
arr.append(j)
return ' '.join(arr)
python strings python-2.x
$endgroup$
1
$begingroup$
...why are you iterating over a dictionary instead of using the accessor?
$endgroup$
– Nic Hartley
Dec 27 '17 at 6:07
1
$begingroup$
What should happen to á, ß, ç, Ø, θ or ж ?
$endgroup$
– Pieter B
Dec 27 '17 at 8:27
$begingroup$
@PieterB in this specific case it ignores those letters, since the goal is to get only alphabet letters(English).
$endgroup$
– nexla
Dec 27 '17 at 9:44
$begingroup$
@nexla sorry for being nit-picking, I saw what the code did, but getting clear requirement is always the start of having good software.
$endgroup$
– Pieter B
Dec 27 '17 at 10:05
add a comment |
$begingroup$
If anything in the text isn't a letter, ignore it and don't return it.
a
being1
,b
being2
, etc.
As an example:
alphabet_position("The sunset sets at twelve o' clock.")
Should return
"20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3
11" as a string.
It is my naive solution and my code is below in python 2.7
def alphabet_position(text):
dictt = 'a':'1','b':'2','c':'3','d':'4','e':'5','f':'6','g':'7','h':'8',
'i':'9','j':'10','k':'11','l':'12','m':'13','n':'14','o':'15','p':'16','q':'17',
'r':'18','s':'19','t':'20','u':'21','v':'22','w':'23','x':'24','y':'25','z':'26'
arr = []
new_text = text.lower()
for i in list(new_text):
for k, j in dictt.iteritems():
if k == i:
arr.append(j)
return ' '.join(arr)
python strings python-2.x
$endgroup$
If anything in the text isn't a letter, ignore it and don't return it.
a
being1
,b
being2
, etc.
As an example:
alphabet_position("The sunset sets at twelve o' clock.")
Should return
"20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3
11" as a string.
It is my naive solution and my code is below in python 2.7
def alphabet_position(text):
dictt = 'a':'1','b':'2','c':'3','d':'4','e':'5','f':'6','g':'7','h':'8',
'i':'9','j':'10','k':'11','l':'12','m':'13','n':'14','o':'15','p':'16','q':'17',
'r':'18','s':'19','t':'20','u':'21','v':'22','w':'23','x':'24','y':'25','z':'26'
arr = []
new_text = text.lower()
for i in list(new_text):
for k, j in dictt.iteritems():
if k == i:
arr.append(j)
return ' '.join(arr)
python strings python-2.x
python strings python-2.x
edited Dec 26 '17 at 18:07
яүυк
7,19122054
7,19122054
asked Dec 26 '17 at 17:08
nexlanexla
123118
123118
1
$begingroup$
...why are you iterating over a dictionary instead of using the accessor?
$endgroup$
– Nic Hartley
Dec 27 '17 at 6:07
1
$begingroup$
What should happen to á, ß, ç, Ø, θ or ж ?
$endgroup$
– Pieter B
Dec 27 '17 at 8:27
$begingroup$
@PieterB in this specific case it ignores those letters, since the goal is to get only alphabet letters(English).
$endgroup$
– nexla
Dec 27 '17 at 9:44
$begingroup$
@nexla sorry for being nit-picking, I saw what the code did, but getting clear requirement is always the start of having good software.
$endgroup$
– Pieter B
Dec 27 '17 at 10:05
add a comment |
1
$begingroup$
...why are you iterating over a dictionary instead of using the accessor?
$endgroup$
– Nic Hartley
Dec 27 '17 at 6:07
1
$begingroup$
What should happen to á, ß, ç, Ø, θ or ж ?
$endgroup$
– Pieter B
Dec 27 '17 at 8:27
$begingroup$
@PieterB in this specific case it ignores those letters, since the goal is to get only alphabet letters(English).
$endgroup$
– nexla
Dec 27 '17 at 9:44
$begingroup$
@nexla sorry for being nit-picking, I saw what the code did, but getting clear requirement is always the start of having good software.
$endgroup$
– Pieter B
Dec 27 '17 at 10:05
1
1
$begingroup$
...why are you iterating over a dictionary instead of using the accessor?
$endgroup$
– Nic Hartley
Dec 27 '17 at 6:07
$begingroup$
...why are you iterating over a dictionary instead of using the accessor?
$endgroup$
– Nic Hartley
Dec 27 '17 at 6:07
1
1
$begingroup$
What should happen to á, ß, ç, Ø, θ or ж ?
$endgroup$
– Pieter B
Dec 27 '17 at 8:27
$begingroup$
What should happen to á, ß, ç, Ø, θ or ж ?
$endgroup$
– Pieter B
Dec 27 '17 at 8:27
$begingroup$
@PieterB in this specific case it ignores those letters, since the goal is to get only alphabet letters(English).
$endgroup$
– nexla
Dec 27 '17 at 9:44
$begingroup$
@PieterB in this specific case it ignores those letters, since the goal is to get only alphabet letters(English).
$endgroup$
– nexla
Dec 27 '17 at 9:44
$begingroup$
@nexla sorry for being nit-picking, I saw what the code did, but getting clear requirement is always the start of having good software.
$endgroup$
– Pieter B
Dec 27 '17 at 10:05
$begingroup$
@nexla sorry for being nit-picking, I saw what the code did, but getting clear requirement is always the start of having good software.
$endgroup$
– Pieter B
Dec 27 '17 at 10:05
add a comment |
5 Answers
5
active
oldest
votes
$begingroup$
First of all, you don't need to hardcode the letters and their positions in the alphabet - you can use the string.ascii_lowercase
.
Also, you don't have to call list()
on a new_text
- you can just iterate over it character by character.
Then, what if we would construct a mapping between letters and letter indexes in the alphabet (with the help of enumerate()
). Then, use a list comprehension to create an array of numbers which we then join to produce a result:
from string import ascii_lowercase
LETTERS = letter: str(index) for index, letter in enumerate(ascii_lowercase, start=1)
def alphabet_position(text):
text = text.lower()
numbers = [LETTERS[character] for character in text if character in LETTERS]
return ' '.join(numbers)
$endgroup$
$begingroup$
Would[LETTERS.get(character) for character in text]
be better? Also, if we want to optimize for speed, I think that for a long text it would be better to generate a dictionary for upper and lower case letters upfront and then save time not doinglower()
for each letter (after all, you're essentially iterating over the string twice, once to put everything in lower case, and again to convert to cumbers).
$endgroup$
– Acccumulation
Dec 27 '17 at 17:50
$begingroup$
@Acccumulation I like the idea of not lowering the string, classic space-time sacrifice, thanks!
$endgroup$
– alecxe
Dec 27 '17 at 18:06
$begingroup$
Minor nitpick:numbers
could be a generator :numbers = (LETTERS[character] for character in text if character in LETTERS)
$endgroup$
– Eric Duminil
Dec 27 '17 at 21:32
$begingroup$
@EricDuminil It could, but last time I checked, joining a list was slightly faster than joining a generator, because in cPythonstr.join
first consumes the generator into a list, internally. It needs to do that to know how much space to allocate for the string. See for example stackoverflow.com/a/37782238.
$endgroup$
– Graipher
Dec 28 '17 at 11:04
add a comment |
$begingroup$
Another slightly different approach than what @alecxe proposed (well, not so different ^_^), would be to use Python's builtins count
and zip
to generate the mapping between letters and their position in the alphabet.
from itertools import count
from string import ascii_lowercase
def letter_indexes(text):
text = text.lower()
letter_mapping = dict(zip(ascii_lowercase, count(1)))
indexes = [
letter_mapping[letter] for letter in text
if letter in letter_mapping
]
return ' '.join(str(index) for index in indexes)
$endgroup$
add a comment |
$begingroup$
If you only care about ASCII characters, you can also exploit the fact that their character codes go from 97 for 'a' to 122 for 'z', contiguously, and do something like
def alphabet_position(text):
nums = [str(ord(x) - 96) for x in text.lower() if x >= 'a' and x <= 'z']
return " ".join(nums)
Note, however, that it may give an impression of being faster than the @alecxe's solution, but is, in fact, quite a lot slower for long input strings, because calling str()
and ord()
on every input character is slower than dictionary lookup. Gives about the same or even slightly better performance for repeated calls on short input strings, but only because (UPD.: no, not anymore). If that matters.letters
dictionary is constructed anew on every call of @alecxe's function, which is easy to change.
$endgroup$
$begingroup$
Good point about the letters dictionary being re-initialized on every call - moved to a proper “constant”. Thanks!
$endgroup$
– alecxe
Dec 27 '17 at 3:58
$begingroup$
I'm too lazy to write speed tests, but I'd imagine thatbytes( ... generate bytes ... ).encode('ascii')
would be faster than callingstr
on each character.
$endgroup$
– wvxvw
Dec 27 '17 at 6:23
add a comment |
$begingroup$
Finally, after a lot of head-banging, I found a way to avoid calling ord()
, which, apparently, is very expensive. Below is the test code and results:
from timeit import timeit
from itertools import count
from string import ascii_lowercase
def alphabet_position_Headcrab(text):
nums = [str(ord(x) - 96) for x in text.lower() if x >= 'a' and x <= 'z']
return " ".join(nums)
def alphabet_position_wvxvw(text):
result, i = [32, 32, 32] * len(text), 0
for c in bytes(text.lower(), 'ascii'):
if 97 <= c < 106:
result[i] = c - 48
i += 2
elif 106 <= c < 116:
result[i] = 49
result[i + 1] = c - 58
i += 3
elif 116 <= c <= 122:
result[i] = 50
result[i + 1] = c - 68
i += 3
return bytes(result[:i-1])
def letter_indexes(text):
text = text.lower()
letter_mapping = dict(zip(ascii_lowercase, count(1)))
indexes = [
letter_mapping[letter] for letter in text
if letter in letter_mapping
]
return ' '.join(str(index) for index in indexes)
def test(f):
data = "The sunset sets at twelve o' clock."
for _ in range(5):
f(data)
data = data + data
def speed_compare():
results =
'wvxvw': timeit(
'test(alphabet_position_wvxvw)',
setup='from __main__ import (test, alphabet_position_wvxvw)',
number=10000,
),
'Headcrab': timeit(
'test(alphabet_position_Headcrab)',
setup='from __main__ import (test, alphabet_position_Headcrab)',
number=10000,
),
'MrGrj': timeit(
'test(letter_indexes)',
setup=(
'from __main__ import (test, letter_indexes)n'
'from itertools import countn'
'from string import ascii_lowercasen'
),
number=10000,
)
for k, v in results.items():
print(k, 'scored', v)
Running speed_compare()
gives this output:
wvxvw scored 1.7537127458490431
Headcrab scored 2.346936965826899
MrGrj scored 2.2078608609735966
$endgroup$
3
$begingroup$
I guess this is a solution to the problem, but in my taste it is way too ambiguous and complicated for the relatively simple problem.
$endgroup$
– Daniel
Dec 27 '17 at 10:01
$begingroup$
Isn't the solution given by @alecxe still faster? When I checked it on an English translation of "Anna Karenina", it was about 3 times faster than my code, by that estimate should be faster than yours, too.
$endgroup$
– Headcrab
Dec 27 '17 at 10:56
$begingroup$
@Headcrab I don't know how to measure it: it has non-trivial setup code, which is also part of the solution to the problem. If I include this setup code in each test, then it won't be much different from MrGrj's code, else, it feels unfair because some work needed to solve the problem is being done outside the test.
$endgroup$
– wvxvw
Dec 27 '17 at 11:15
add a comment |
$begingroup$
Seems complicated with all the libraries requirements for this simple problem. I'm not proficient in Python syntax but I know this can be done. Let me explain in pseudocode (syntax can be looked up by you):
1. Declare a list (or array as I call it in other langs) of alphabet[]="'a', 'b',....'z'"
Their index position is ALREADY their positions...so, position of 'a'is 0 (because Python index is 0-based; if you don't like it, you can just add 1 to the result to show results counting from 1)
(lowercase or uppercase, doesn't matter since you're looking at the position of them in either case not their ord values)
2. Get the string to compare and its length: len(astring)
For that length, iterate and find the character (achar for example) in the string (astring for example). Either for loop or some magical python 1-line stmnts like: for achar in astring
If you use a 1-line stmtnt insted of a loop, you'd probably have to load them into another list and loop in that. Not sure, I like for loops, so...
Inside the for loop, check each achar's index location if chr(x) == astring[i] for example where i is loop counter, then load that location into a new array (define an empty array outside of the loop first) say, "positions[]"
3. After the loop ends, positions[] should have the positions (0-based) of each matching char. You could add 1 to each value if you want position to be 1-based.
Sorry, I couldn't write the whole code mainly because my syntax knowledge isn't very good in Python yet, but the logic should make sense, right?
New contributor
$endgroup$
1
$begingroup$
Welcome to CR Tony, This answer doesn't look like it is reviewing code, and your answer is not readable. Please see editing help.
$endgroup$
– 422_unprocessable_entity
58 mins ago
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f183658%2freplacing-letters-with-numbers-with-its-position-in-alphabet%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
First of all, you don't need to hardcode the letters and their positions in the alphabet - you can use the string.ascii_lowercase
.
Also, you don't have to call list()
on a new_text
- you can just iterate over it character by character.
Then, what if we would construct a mapping between letters and letter indexes in the alphabet (with the help of enumerate()
). Then, use a list comprehension to create an array of numbers which we then join to produce a result:
from string import ascii_lowercase
LETTERS = letter: str(index) for index, letter in enumerate(ascii_lowercase, start=1)
def alphabet_position(text):
text = text.lower()
numbers = [LETTERS[character] for character in text if character in LETTERS]
return ' '.join(numbers)
$endgroup$
$begingroup$
Would[LETTERS.get(character) for character in text]
be better? Also, if we want to optimize for speed, I think that for a long text it would be better to generate a dictionary for upper and lower case letters upfront and then save time not doinglower()
for each letter (after all, you're essentially iterating over the string twice, once to put everything in lower case, and again to convert to cumbers).
$endgroup$
– Acccumulation
Dec 27 '17 at 17:50
$begingroup$
@Acccumulation I like the idea of not lowering the string, classic space-time sacrifice, thanks!
$endgroup$
– alecxe
Dec 27 '17 at 18:06
$begingroup$
Minor nitpick:numbers
could be a generator :numbers = (LETTERS[character] for character in text if character in LETTERS)
$endgroup$
– Eric Duminil
Dec 27 '17 at 21:32
$begingroup$
@EricDuminil It could, but last time I checked, joining a list was slightly faster than joining a generator, because in cPythonstr.join
first consumes the generator into a list, internally. It needs to do that to know how much space to allocate for the string. See for example stackoverflow.com/a/37782238.
$endgroup$
– Graipher
Dec 28 '17 at 11:04
add a comment |
$begingroup$
First of all, you don't need to hardcode the letters and their positions in the alphabet - you can use the string.ascii_lowercase
.
Also, you don't have to call list()
on a new_text
- you can just iterate over it character by character.
Then, what if we would construct a mapping between letters and letter indexes in the alphabet (with the help of enumerate()
). Then, use a list comprehension to create an array of numbers which we then join to produce a result:
from string import ascii_lowercase
LETTERS = letter: str(index) for index, letter in enumerate(ascii_lowercase, start=1)
def alphabet_position(text):
text = text.lower()
numbers = [LETTERS[character] for character in text if character in LETTERS]
return ' '.join(numbers)
$endgroup$
$begingroup$
Would[LETTERS.get(character) for character in text]
be better? Also, if we want to optimize for speed, I think that for a long text it would be better to generate a dictionary for upper and lower case letters upfront and then save time not doinglower()
for each letter (after all, you're essentially iterating over the string twice, once to put everything in lower case, and again to convert to cumbers).
$endgroup$
– Acccumulation
Dec 27 '17 at 17:50
$begingroup$
@Acccumulation I like the idea of not lowering the string, classic space-time sacrifice, thanks!
$endgroup$
– alecxe
Dec 27 '17 at 18:06
$begingroup$
Minor nitpick:numbers
could be a generator :numbers = (LETTERS[character] for character in text if character in LETTERS)
$endgroup$
– Eric Duminil
Dec 27 '17 at 21:32
$begingroup$
@EricDuminil It could, but last time I checked, joining a list was slightly faster than joining a generator, because in cPythonstr.join
first consumes the generator into a list, internally. It needs to do that to know how much space to allocate for the string. See for example stackoverflow.com/a/37782238.
$endgroup$
– Graipher
Dec 28 '17 at 11:04
add a comment |
$begingroup$
First of all, you don't need to hardcode the letters and their positions in the alphabet - you can use the string.ascii_lowercase
.
Also, you don't have to call list()
on a new_text
- you can just iterate over it character by character.
Then, what if we would construct a mapping between letters and letter indexes in the alphabet (with the help of enumerate()
). Then, use a list comprehension to create an array of numbers which we then join to produce a result:
from string import ascii_lowercase
LETTERS = letter: str(index) for index, letter in enumerate(ascii_lowercase, start=1)
def alphabet_position(text):
text = text.lower()
numbers = [LETTERS[character] for character in text if character in LETTERS]
return ' '.join(numbers)
$endgroup$
First of all, you don't need to hardcode the letters and their positions in the alphabet - you can use the string.ascii_lowercase
.
Also, you don't have to call list()
on a new_text
- you can just iterate over it character by character.
Then, what if we would construct a mapping between letters and letter indexes in the alphabet (with the help of enumerate()
). Then, use a list comprehension to create an array of numbers which we then join to produce a result:
from string import ascii_lowercase
LETTERS = letter: str(index) for index, letter in enumerate(ascii_lowercase, start=1)
def alphabet_position(text):
text = text.lower()
numbers = [LETTERS[character] for character in text if character in LETTERS]
return ' '.join(numbers)
edited Dec 27 '17 at 3:57
answered Dec 26 '17 at 17:29
alecxealecxe
15.3k53580
15.3k53580
$begingroup$
Would[LETTERS.get(character) for character in text]
be better? Also, if we want to optimize for speed, I think that for a long text it would be better to generate a dictionary for upper and lower case letters upfront and then save time not doinglower()
for each letter (after all, you're essentially iterating over the string twice, once to put everything in lower case, and again to convert to cumbers).
$endgroup$
– Acccumulation
Dec 27 '17 at 17:50
$begingroup$
@Acccumulation I like the idea of not lowering the string, classic space-time sacrifice, thanks!
$endgroup$
– alecxe
Dec 27 '17 at 18:06
$begingroup$
Minor nitpick:numbers
could be a generator :numbers = (LETTERS[character] for character in text if character in LETTERS)
$endgroup$
– Eric Duminil
Dec 27 '17 at 21:32
$begingroup$
@EricDuminil It could, but last time I checked, joining a list was slightly faster than joining a generator, because in cPythonstr.join
first consumes the generator into a list, internally. It needs to do that to know how much space to allocate for the string. See for example stackoverflow.com/a/37782238.
$endgroup$
– Graipher
Dec 28 '17 at 11:04
add a comment |
$begingroup$
Would[LETTERS.get(character) for character in text]
be better? Also, if we want to optimize for speed, I think that for a long text it would be better to generate a dictionary for upper and lower case letters upfront and then save time not doinglower()
for each letter (after all, you're essentially iterating over the string twice, once to put everything in lower case, and again to convert to cumbers).
$endgroup$
– Acccumulation
Dec 27 '17 at 17:50
$begingroup$
@Acccumulation I like the idea of not lowering the string, classic space-time sacrifice, thanks!
$endgroup$
– alecxe
Dec 27 '17 at 18:06
$begingroup$
Minor nitpick:numbers
could be a generator :numbers = (LETTERS[character] for character in text if character in LETTERS)
$endgroup$
– Eric Duminil
Dec 27 '17 at 21:32
$begingroup$
@EricDuminil It could, but last time I checked, joining a list was slightly faster than joining a generator, because in cPythonstr.join
first consumes the generator into a list, internally. It needs to do that to know how much space to allocate for the string. See for example stackoverflow.com/a/37782238.
$endgroup$
– Graipher
Dec 28 '17 at 11:04
$begingroup$
Would
[LETTERS.get(character) for character in text]
be better? Also, if we want to optimize for speed, I think that for a long text it would be better to generate a dictionary for upper and lower case letters upfront and then save time not doing lower()
for each letter (after all, you're essentially iterating over the string twice, once to put everything in lower case, and again to convert to cumbers).$endgroup$
– Acccumulation
Dec 27 '17 at 17:50
$begingroup$
Would
[LETTERS.get(character) for character in text]
be better? Also, if we want to optimize for speed, I think that for a long text it would be better to generate a dictionary for upper and lower case letters upfront and then save time not doing lower()
for each letter (after all, you're essentially iterating over the string twice, once to put everything in lower case, and again to convert to cumbers).$endgroup$
– Acccumulation
Dec 27 '17 at 17:50
$begingroup$
@Acccumulation I like the idea of not lowering the string, classic space-time sacrifice, thanks!
$endgroup$
– alecxe
Dec 27 '17 at 18:06
$begingroup$
@Acccumulation I like the idea of not lowering the string, classic space-time sacrifice, thanks!
$endgroup$
– alecxe
Dec 27 '17 at 18:06
$begingroup$
Minor nitpick:
numbers
could be a generator : numbers = (LETTERS[character] for character in text if character in LETTERS)
$endgroup$
– Eric Duminil
Dec 27 '17 at 21:32
$begingroup$
Minor nitpick:
numbers
could be a generator : numbers = (LETTERS[character] for character in text if character in LETTERS)
$endgroup$
– Eric Duminil
Dec 27 '17 at 21:32
$begingroup$
@EricDuminil It could, but last time I checked, joining a list was slightly faster than joining a generator, because in cPython
str.join
first consumes the generator into a list, internally. It needs to do that to know how much space to allocate for the string. See for example stackoverflow.com/a/37782238.$endgroup$
– Graipher
Dec 28 '17 at 11:04
$begingroup$
@EricDuminil It could, but last time I checked, joining a list was slightly faster than joining a generator, because in cPython
str.join
first consumes the generator into a list, internally. It needs to do that to know how much space to allocate for the string. See for example stackoverflow.com/a/37782238.$endgroup$
– Graipher
Dec 28 '17 at 11:04
add a comment |
$begingroup$
Another slightly different approach than what @alecxe proposed (well, not so different ^_^), would be to use Python's builtins count
and zip
to generate the mapping between letters and their position in the alphabet.
from itertools import count
from string import ascii_lowercase
def letter_indexes(text):
text = text.lower()
letter_mapping = dict(zip(ascii_lowercase, count(1)))
indexes = [
letter_mapping[letter] for letter in text
if letter in letter_mapping
]
return ' '.join(str(index) for index in indexes)
$endgroup$
add a comment |
$begingroup$
Another slightly different approach than what @alecxe proposed (well, not so different ^_^), would be to use Python's builtins count
and zip
to generate the mapping between letters and their position in the alphabet.
from itertools import count
from string import ascii_lowercase
def letter_indexes(text):
text = text.lower()
letter_mapping = dict(zip(ascii_lowercase, count(1)))
indexes = [
letter_mapping[letter] for letter in text
if letter in letter_mapping
]
return ' '.join(str(index) for index in indexes)
$endgroup$
add a comment |
$begingroup$
Another slightly different approach than what @alecxe proposed (well, not so different ^_^), would be to use Python's builtins count
and zip
to generate the mapping between letters and their position in the alphabet.
from itertools import count
from string import ascii_lowercase
def letter_indexes(text):
text = text.lower()
letter_mapping = dict(zip(ascii_lowercase, count(1)))
indexes = [
letter_mapping[letter] for letter in text
if letter in letter_mapping
]
return ' '.join(str(index) for index in indexes)
$endgroup$
Another slightly different approach than what @alecxe proposed (well, not so different ^_^), would be to use Python's builtins count
and zip
to generate the mapping between letters and their position in the alphabet.
from itertools import count
from string import ascii_lowercase
def letter_indexes(text):
text = text.lower()
letter_mapping = dict(zip(ascii_lowercase, count(1)))
indexes = [
letter_mapping[letter] for letter in text
if letter in letter_mapping
]
return ' '.join(str(index) for index in indexes)
answered Dec 26 '17 at 18:36
яүυкяүυк
7,19122054
7,19122054
add a comment |
add a comment |
$begingroup$
If you only care about ASCII characters, you can also exploit the fact that their character codes go from 97 for 'a' to 122 for 'z', contiguously, and do something like
def alphabet_position(text):
nums = [str(ord(x) - 96) for x in text.lower() if x >= 'a' and x <= 'z']
return " ".join(nums)
Note, however, that it may give an impression of being faster than the @alecxe's solution, but is, in fact, quite a lot slower for long input strings, because calling str()
and ord()
on every input character is slower than dictionary lookup. Gives about the same or even slightly better performance for repeated calls on short input strings, but only because (UPD.: no, not anymore). If that matters.letters
dictionary is constructed anew on every call of @alecxe's function, which is easy to change.
$endgroup$
$begingroup$
Good point about the letters dictionary being re-initialized on every call - moved to a proper “constant”. Thanks!
$endgroup$
– alecxe
Dec 27 '17 at 3:58
$begingroup$
I'm too lazy to write speed tests, but I'd imagine thatbytes( ... generate bytes ... ).encode('ascii')
would be faster than callingstr
on each character.
$endgroup$
– wvxvw
Dec 27 '17 at 6:23
add a comment |
$begingroup$
If you only care about ASCII characters, you can also exploit the fact that their character codes go from 97 for 'a' to 122 for 'z', contiguously, and do something like
def alphabet_position(text):
nums = [str(ord(x) - 96) for x in text.lower() if x >= 'a' and x <= 'z']
return " ".join(nums)
Note, however, that it may give an impression of being faster than the @alecxe's solution, but is, in fact, quite a lot slower for long input strings, because calling str()
and ord()
on every input character is slower than dictionary lookup. Gives about the same or even slightly better performance for repeated calls on short input strings, but only because (UPD.: no, not anymore). If that matters.letters
dictionary is constructed anew on every call of @alecxe's function, which is easy to change.
$endgroup$
$begingroup$
Good point about the letters dictionary being re-initialized on every call - moved to a proper “constant”. Thanks!
$endgroup$
– alecxe
Dec 27 '17 at 3:58
$begingroup$
I'm too lazy to write speed tests, but I'd imagine thatbytes( ... generate bytes ... ).encode('ascii')
would be faster than callingstr
on each character.
$endgroup$
– wvxvw
Dec 27 '17 at 6:23
add a comment |
$begingroup$
If you only care about ASCII characters, you can also exploit the fact that their character codes go from 97 for 'a' to 122 for 'z', contiguously, and do something like
def alphabet_position(text):
nums = [str(ord(x) - 96) for x in text.lower() if x >= 'a' and x <= 'z']
return " ".join(nums)
Note, however, that it may give an impression of being faster than the @alecxe's solution, but is, in fact, quite a lot slower for long input strings, because calling str()
and ord()
on every input character is slower than dictionary lookup. Gives about the same or even slightly better performance for repeated calls on short input strings, but only because (UPD.: no, not anymore). If that matters.letters
dictionary is constructed anew on every call of @alecxe's function, which is easy to change.
$endgroup$
If you only care about ASCII characters, you can also exploit the fact that their character codes go from 97 for 'a' to 122 for 'z', contiguously, and do something like
def alphabet_position(text):
nums = [str(ord(x) - 96) for x in text.lower() if x >= 'a' and x <= 'z']
return " ".join(nums)
Note, however, that it may give an impression of being faster than the @alecxe's solution, but is, in fact, quite a lot slower for long input strings, because calling str()
and ord()
on every input character is slower than dictionary lookup. Gives about the same or even slightly better performance for repeated calls on short input strings, but only because (UPD.: no, not anymore). If that matters.letters
dictionary is constructed anew on every call of @alecxe's function, which is easy to change.
edited Dec 27 '17 at 5:43
answered Dec 27 '17 at 3:36
HeadcrabHeadcrab
1613
1613
$begingroup$
Good point about the letters dictionary being re-initialized on every call - moved to a proper “constant”. Thanks!
$endgroup$
– alecxe
Dec 27 '17 at 3:58
$begingroup$
I'm too lazy to write speed tests, but I'd imagine thatbytes( ... generate bytes ... ).encode('ascii')
would be faster than callingstr
on each character.
$endgroup$
– wvxvw
Dec 27 '17 at 6:23
add a comment |
$begingroup$
Good point about the letters dictionary being re-initialized on every call - moved to a proper “constant”. Thanks!
$endgroup$
– alecxe
Dec 27 '17 at 3:58
$begingroup$
I'm too lazy to write speed tests, but I'd imagine thatbytes( ... generate bytes ... ).encode('ascii')
would be faster than callingstr
on each character.
$endgroup$
– wvxvw
Dec 27 '17 at 6:23
$begingroup$
Good point about the letters dictionary being re-initialized on every call - moved to a proper “constant”. Thanks!
$endgroup$
– alecxe
Dec 27 '17 at 3:58
$begingroup$
Good point about the letters dictionary being re-initialized on every call - moved to a proper “constant”. Thanks!
$endgroup$
– alecxe
Dec 27 '17 at 3:58
$begingroup$
I'm too lazy to write speed tests, but I'd imagine that
bytes( ... generate bytes ... ).encode('ascii')
would be faster than calling str
on each character.$endgroup$
– wvxvw
Dec 27 '17 at 6:23
$begingroup$
I'm too lazy to write speed tests, but I'd imagine that
bytes( ... generate bytes ... ).encode('ascii')
would be faster than calling str
on each character.$endgroup$
– wvxvw
Dec 27 '17 at 6:23
add a comment |
$begingroup$
Finally, after a lot of head-banging, I found a way to avoid calling ord()
, which, apparently, is very expensive. Below is the test code and results:
from timeit import timeit
from itertools import count
from string import ascii_lowercase
def alphabet_position_Headcrab(text):
nums = [str(ord(x) - 96) for x in text.lower() if x >= 'a' and x <= 'z']
return " ".join(nums)
def alphabet_position_wvxvw(text):
result, i = [32, 32, 32] * len(text), 0
for c in bytes(text.lower(), 'ascii'):
if 97 <= c < 106:
result[i] = c - 48
i += 2
elif 106 <= c < 116:
result[i] = 49
result[i + 1] = c - 58
i += 3
elif 116 <= c <= 122:
result[i] = 50
result[i + 1] = c - 68
i += 3
return bytes(result[:i-1])
def letter_indexes(text):
text = text.lower()
letter_mapping = dict(zip(ascii_lowercase, count(1)))
indexes = [
letter_mapping[letter] for letter in text
if letter in letter_mapping
]
return ' '.join(str(index) for index in indexes)
def test(f):
data = "The sunset sets at twelve o' clock."
for _ in range(5):
f(data)
data = data + data
def speed_compare():
results =
'wvxvw': timeit(
'test(alphabet_position_wvxvw)',
setup='from __main__ import (test, alphabet_position_wvxvw)',
number=10000,
),
'Headcrab': timeit(
'test(alphabet_position_Headcrab)',
setup='from __main__ import (test, alphabet_position_Headcrab)',
number=10000,
),
'MrGrj': timeit(
'test(letter_indexes)',
setup=(
'from __main__ import (test, letter_indexes)n'
'from itertools import countn'
'from string import ascii_lowercasen'
),
number=10000,
)
for k, v in results.items():
print(k, 'scored', v)
Running speed_compare()
gives this output:
wvxvw scored 1.7537127458490431
Headcrab scored 2.346936965826899
MrGrj scored 2.2078608609735966
$endgroup$
3
$begingroup$
I guess this is a solution to the problem, but in my taste it is way too ambiguous and complicated for the relatively simple problem.
$endgroup$
– Daniel
Dec 27 '17 at 10:01
$begingroup$
Isn't the solution given by @alecxe still faster? When I checked it on an English translation of "Anna Karenina", it was about 3 times faster than my code, by that estimate should be faster than yours, too.
$endgroup$
– Headcrab
Dec 27 '17 at 10:56
$begingroup$
@Headcrab I don't know how to measure it: it has non-trivial setup code, which is also part of the solution to the problem. If I include this setup code in each test, then it won't be much different from MrGrj's code, else, it feels unfair because some work needed to solve the problem is being done outside the test.
$endgroup$
– wvxvw
Dec 27 '17 at 11:15
add a comment |
$begingroup$
Finally, after a lot of head-banging, I found a way to avoid calling ord()
, which, apparently, is very expensive. Below is the test code and results:
from timeit import timeit
from itertools import count
from string import ascii_lowercase
def alphabet_position_Headcrab(text):
nums = [str(ord(x) - 96) for x in text.lower() if x >= 'a' and x <= 'z']
return " ".join(nums)
def alphabet_position_wvxvw(text):
result, i = [32, 32, 32] * len(text), 0
for c in bytes(text.lower(), 'ascii'):
if 97 <= c < 106:
result[i] = c - 48
i += 2
elif 106 <= c < 116:
result[i] = 49
result[i + 1] = c - 58
i += 3
elif 116 <= c <= 122:
result[i] = 50
result[i + 1] = c - 68
i += 3
return bytes(result[:i-1])
def letter_indexes(text):
text = text.lower()
letter_mapping = dict(zip(ascii_lowercase, count(1)))
indexes = [
letter_mapping[letter] for letter in text
if letter in letter_mapping
]
return ' '.join(str(index) for index in indexes)
def test(f):
data = "The sunset sets at twelve o' clock."
for _ in range(5):
f(data)
data = data + data
def speed_compare():
results =
'wvxvw': timeit(
'test(alphabet_position_wvxvw)',
setup='from __main__ import (test, alphabet_position_wvxvw)',
number=10000,
),
'Headcrab': timeit(
'test(alphabet_position_Headcrab)',
setup='from __main__ import (test, alphabet_position_Headcrab)',
number=10000,
),
'MrGrj': timeit(
'test(letter_indexes)',
setup=(
'from __main__ import (test, letter_indexes)n'
'from itertools import countn'
'from string import ascii_lowercasen'
),
number=10000,
)
for k, v in results.items():
print(k, 'scored', v)
Running speed_compare()
gives this output:
wvxvw scored 1.7537127458490431
Headcrab scored 2.346936965826899
MrGrj scored 2.2078608609735966
$endgroup$
3
$begingroup$
I guess this is a solution to the problem, but in my taste it is way too ambiguous and complicated for the relatively simple problem.
$endgroup$
– Daniel
Dec 27 '17 at 10:01
$begingroup$
Isn't the solution given by @alecxe still faster? When I checked it on an English translation of "Anna Karenina", it was about 3 times faster than my code, by that estimate should be faster than yours, too.
$endgroup$
– Headcrab
Dec 27 '17 at 10:56
$begingroup$
@Headcrab I don't know how to measure it: it has non-trivial setup code, which is also part of the solution to the problem. If I include this setup code in each test, then it won't be much different from MrGrj's code, else, it feels unfair because some work needed to solve the problem is being done outside the test.
$endgroup$
– wvxvw
Dec 27 '17 at 11:15
add a comment |
$begingroup$
Finally, after a lot of head-banging, I found a way to avoid calling ord()
, which, apparently, is very expensive. Below is the test code and results:
from timeit import timeit
from itertools import count
from string import ascii_lowercase
def alphabet_position_Headcrab(text):
nums = [str(ord(x) - 96) for x in text.lower() if x >= 'a' and x <= 'z']
return " ".join(nums)
def alphabet_position_wvxvw(text):
result, i = [32, 32, 32] * len(text), 0
for c in bytes(text.lower(), 'ascii'):
if 97 <= c < 106:
result[i] = c - 48
i += 2
elif 106 <= c < 116:
result[i] = 49
result[i + 1] = c - 58
i += 3
elif 116 <= c <= 122:
result[i] = 50
result[i + 1] = c - 68
i += 3
return bytes(result[:i-1])
def letter_indexes(text):
text = text.lower()
letter_mapping = dict(zip(ascii_lowercase, count(1)))
indexes = [
letter_mapping[letter] for letter in text
if letter in letter_mapping
]
return ' '.join(str(index) for index in indexes)
def test(f):
data = "The sunset sets at twelve o' clock."
for _ in range(5):
f(data)
data = data + data
def speed_compare():
results =
'wvxvw': timeit(
'test(alphabet_position_wvxvw)',
setup='from __main__ import (test, alphabet_position_wvxvw)',
number=10000,
),
'Headcrab': timeit(
'test(alphabet_position_Headcrab)',
setup='from __main__ import (test, alphabet_position_Headcrab)',
number=10000,
),
'MrGrj': timeit(
'test(letter_indexes)',
setup=(
'from __main__ import (test, letter_indexes)n'
'from itertools import countn'
'from string import ascii_lowercasen'
),
number=10000,
)
for k, v in results.items():
print(k, 'scored', v)
Running speed_compare()
gives this output:
wvxvw scored 1.7537127458490431
Headcrab scored 2.346936965826899
MrGrj scored 2.2078608609735966
$endgroup$
Finally, after a lot of head-banging, I found a way to avoid calling ord()
, which, apparently, is very expensive. Below is the test code and results:
from timeit import timeit
from itertools import count
from string import ascii_lowercase
def alphabet_position_Headcrab(text):
nums = [str(ord(x) - 96) for x in text.lower() if x >= 'a' and x <= 'z']
return " ".join(nums)
def alphabet_position_wvxvw(text):
result, i = [32, 32, 32] * len(text), 0
for c in bytes(text.lower(), 'ascii'):
if 97 <= c < 106:
result[i] = c - 48
i += 2
elif 106 <= c < 116:
result[i] = 49
result[i + 1] = c - 58
i += 3
elif 116 <= c <= 122:
result[i] = 50
result[i + 1] = c - 68
i += 3
return bytes(result[:i-1])
def letter_indexes(text):
text = text.lower()
letter_mapping = dict(zip(ascii_lowercase, count(1)))
indexes = [
letter_mapping[letter] for letter in text
if letter in letter_mapping
]
return ' '.join(str(index) for index in indexes)
def test(f):
data = "The sunset sets at twelve o' clock."
for _ in range(5):
f(data)
data = data + data
def speed_compare():
results =
'wvxvw': timeit(
'test(alphabet_position_wvxvw)',
setup='from __main__ import (test, alphabet_position_wvxvw)',
number=10000,
),
'Headcrab': timeit(
'test(alphabet_position_Headcrab)',
setup='from __main__ import (test, alphabet_position_Headcrab)',
number=10000,
),
'MrGrj': timeit(
'test(letter_indexes)',
setup=(
'from __main__ import (test, letter_indexes)n'
'from itertools import countn'
'from string import ascii_lowercasen'
),
number=10000,
)
for k, v in results.items():
print(k, 'scored', v)
Running speed_compare()
gives this output:
wvxvw scored 1.7537127458490431
Headcrab scored 2.346936965826899
MrGrj scored 2.2078608609735966
edited Dec 27 '17 at 9:13
answered Dec 27 '17 at 9:06
wvxvwwvxvw
922614
922614
3
$begingroup$
I guess this is a solution to the problem, but in my taste it is way too ambiguous and complicated for the relatively simple problem.
$endgroup$
– Daniel
Dec 27 '17 at 10:01
$begingroup$
Isn't the solution given by @alecxe still faster? When I checked it on an English translation of "Anna Karenina", it was about 3 times faster than my code, by that estimate should be faster than yours, too.
$endgroup$
– Headcrab
Dec 27 '17 at 10:56
$begingroup$
@Headcrab I don't know how to measure it: it has non-trivial setup code, which is also part of the solution to the problem. If I include this setup code in each test, then it won't be much different from MrGrj's code, else, it feels unfair because some work needed to solve the problem is being done outside the test.
$endgroup$
– wvxvw
Dec 27 '17 at 11:15
add a comment |
3
$begingroup$
I guess this is a solution to the problem, but in my taste it is way too ambiguous and complicated for the relatively simple problem.
$endgroup$
– Daniel
Dec 27 '17 at 10:01
$begingroup$
Isn't the solution given by @alecxe still faster? When I checked it on an English translation of "Anna Karenina", it was about 3 times faster than my code, by that estimate should be faster than yours, too.
$endgroup$
– Headcrab
Dec 27 '17 at 10:56
$begingroup$
@Headcrab I don't know how to measure it: it has non-trivial setup code, which is also part of the solution to the problem. If I include this setup code in each test, then it won't be much different from MrGrj's code, else, it feels unfair because some work needed to solve the problem is being done outside the test.
$endgroup$
– wvxvw
Dec 27 '17 at 11:15
3
3
$begingroup$
I guess this is a solution to the problem, but in my taste it is way too ambiguous and complicated for the relatively simple problem.
$endgroup$
– Daniel
Dec 27 '17 at 10:01
$begingroup$
I guess this is a solution to the problem, but in my taste it is way too ambiguous and complicated for the relatively simple problem.
$endgroup$
– Daniel
Dec 27 '17 at 10:01
$begingroup$
Isn't the solution given by @alecxe still faster? When I checked it on an English translation of "Anna Karenina", it was about 3 times faster than my code, by that estimate should be faster than yours, too.
$endgroup$
– Headcrab
Dec 27 '17 at 10:56
$begingroup$
Isn't the solution given by @alecxe still faster? When I checked it on an English translation of "Anna Karenina", it was about 3 times faster than my code, by that estimate should be faster than yours, too.
$endgroup$
– Headcrab
Dec 27 '17 at 10:56
$begingroup$
@Headcrab I don't know how to measure it: it has non-trivial setup code, which is also part of the solution to the problem. If I include this setup code in each test, then it won't be much different from MrGrj's code, else, it feels unfair because some work needed to solve the problem is being done outside the test.
$endgroup$
– wvxvw
Dec 27 '17 at 11:15
$begingroup$
@Headcrab I don't know how to measure it: it has non-trivial setup code, which is also part of the solution to the problem. If I include this setup code in each test, then it won't be much different from MrGrj's code, else, it feels unfair because some work needed to solve the problem is being done outside the test.
$endgroup$
– wvxvw
Dec 27 '17 at 11:15
add a comment |
$begingroup$
Seems complicated with all the libraries requirements for this simple problem. I'm not proficient in Python syntax but I know this can be done. Let me explain in pseudocode (syntax can be looked up by you):
1. Declare a list (or array as I call it in other langs) of alphabet[]="'a', 'b',....'z'"
Their index position is ALREADY their positions...so, position of 'a'is 0 (because Python index is 0-based; if you don't like it, you can just add 1 to the result to show results counting from 1)
(lowercase or uppercase, doesn't matter since you're looking at the position of them in either case not their ord values)
2. Get the string to compare and its length: len(astring)
For that length, iterate and find the character (achar for example) in the string (astring for example). Either for loop or some magical python 1-line stmnts like: for achar in astring
If you use a 1-line stmtnt insted of a loop, you'd probably have to load them into another list and loop in that. Not sure, I like for loops, so...
Inside the for loop, check each achar's index location if chr(x) == astring[i] for example where i is loop counter, then load that location into a new array (define an empty array outside of the loop first) say, "positions[]"
3. After the loop ends, positions[] should have the positions (0-based) of each matching char. You could add 1 to each value if you want position to be 1-based.
Sorry, I couldn't write the whole code mainly because my syntax knowledge isn't very good in Python yet, but the logic should make sense, right?
New contributor
$endgroup$
1
$begingroup$
Welcome to CR Tony, This answer doesn't look like it is reviewing code, and your answer is not readable. Please see editing help.
$endgroup$
– 422_unprocessable_entity
58 mins ago
add a comment |
$begingroup$
Seems complicated with all the libraries requirements for this simple problem. I'm not proficient in Python syntax but I know this can be done. Let me explain in pseudocode (syntax can be looked up by you):
1. Declare a list (or array as I call it in other langs) of alphabet[]="'a', 'b',....'z'"
Their index position is ALREADY their positions...so, position of 'a'is 0 (because Python index is 0-based; if you don't like it, you can just add 1 to the result to show results counting from 1)
(lowercase or uppercase, doesn't matter since you're looking at the position of them in either case not their ord values)
2. Get the string to compare and its length: len(astring)
For that length, iterate and find the character (achar for example) in the string (astring for example). Either for loop or some magical python 1-line stmnts like: for achar in astring
If you use a 1-line stmtnt insted of a loop, you'd probably have to load them into another list and loop in that. Not sure, I like for loops, so...
Inside the for loop, check each achar's index location if chr(x) == astring[i] for example where i is loop counter, then load that location into a new array (define an empty array outside of the loop first) say, "positions[]"
3. After the loop ends, positions[] should have the positions (0-based) of each matching char. You could add 1 to each value if you want position to be 1-based.
Sorry, I couldn't write the whole code mainly because my syntax knowledge isn't very good in Python yet, but the logic should make sense, right?
New contributor
$endgroup$
1
$begingroup$
Welcome to CR Tony, This answer doesn't look like it is reviewing code, and your answer is not readable. Please see editing help.
$endgroup$
– 422_unprocessable_entity
58 mins ago
add a comment |
$begingroup$
Seems complicated with all the libraries requirements for this simple problem. I'm not proficient in Python syntax but I know this can be done. Let me explain in pseudocode (syntax can be looked up by you):
1. Declare a list (or array as I call it in other langs) of alphabet[]="'a', 'b',....'z'"
Their index position is ALREADY their positions...so, position of 'a'is 0 (because Python index is 0-based; if you don't like it, you can just add 1 to the result to show results counting from 1)
(lowercase or uppercase, doesn't matter since you're looking at the position of them in either case not their ord values)
2. Get the string to compare and its length: len(astring)
For that length, iterate and find the character (achar for example) in the string (astring for example). Either for loop or some magical python 1-line stmnts like: for achar in astring
If you use a 1-line stmtnt insted of a loop, you'd probably have to load them into another list and loop in that. Not sure, I like for loops, so...
Inside the for loop, check each achar's index location if chr(x) == astring[i] for example where i is loop counter, then load that location into a new array (define an empty array outside of the loop first) say, "positions[]"
3. After the loop ends, positions[] should have the positions (0-based) of each matching char. You could add 1 to each value if you want position to be 1-based.
Sorry, I couldn't write the whole code mainly because my syntax knowledge isn't very good in Python yet, but the logic should make sense, right?
New contributor
$endgroup$
Seems complicated with all the libraries requirements for this simple problem. I'm not proficient in Python syntax but I know this can be done. Let me explain in pseudocode (syntax can be looked up by you):
1. Declare a list (or array as I call it in other langs) of alphabet[]="'a', 'b',....'z'"
Their index position is ALREADY their positions...so, position of 'a'is 0 (because Python index is 0-based; if you don't like it, you can just add 1 to the result to show results counting from 1)
(lowercase or uppercase, doesn't matter since you're looking at the position of them in either case not their ord values)
2. Get the string to compare and its length: len(astring)
For that length, iterate and find the character (achar for example) in the string (astring for example). Either for loop or some magical python 1-line stmnts like: for achar in astring
If you use a 1-line stmtnt insted of a loop, you'd probably have to load them into another list and loop in that. Not sure, I like for loops, so...
Inside the for loop, check each achar's index location if chr(x) == astring[i] for example where i is loop counter, then load that location into a new array (define an empty array outside of the loop first) say, "positions[]"
3. After the loop ends, positions[] should have the positions (0-based) of each matching char. You could add 1 to each value if you want position to be 1-based.
Sorry, I couldn't write the whole code mainly because my syntax knowledge isn't very good in Python yet, but the logic should make sense, right?
New contributor
New contributor
answered 5 hours ago
Tony RaymanTony Rayman
11
11
New contributor
New contributor
1
$begingroup$
Welcome to CR Tony, This answer doesn't look like it is reviewing code, and your answer is not readable. Please see editing help.
$endgroup$
– 422_unprocessable_entity
58 mins ago
add a comment |
1
$begingroup$
Welcome to CR Tony, This answer doesn't look like it is reviewing code, and your answer is not readable. Please see editing help.
$endgroup$
– 422_unprocessable_entity
58 mins ago
1
1
$begingroup$
Welcome to CR Tony, This answer doesn't look like it is reviewing code, and your answer is not readable. Please see editing help.
$endgroup$
– 422_unprocessable_entity
58 mins ago
$begingroup$
Welcome to CR Tony, This answer doesn't look like it is reviewing code, and your answer is not readable. Please see editing help.
$endgroup$
– 422_unprocessable_entity
58 mins ago
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f183658%2freplacing-letters-with-numbers-with-its-position-in-alphabet%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
$begingroup$
...why are you iterating over a dictionary instead of using the accessor?
$endgroup$
– Nic Hartley
Dec 27 '17 at 6:07
1
$begingroup$
What should happen to á, ß, ç, Ø, θ or ж ?
$endgroup$
– Pieter B
Dec 27 '17 at 8:27
$begingroup$
@PieterB in this specific case it ignores those letters, since the goal is to get only alphabet letters(English).
$endgroup$
– nexla
Dec 27 '17 at 9:44
$begingroup$
@nexla sorry for being nit-picking, I saw what the code did, but getting clear requirement is always the start of having good software.
$endgroup$
– Pieter B
Dec 27 '17 at 10:05