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













20












$begingroup$



If anything in the text isn't a letter, ignore it and don't return it.



a being 1, b being 2, 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)









share|improve this question











$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















20












$begingroup$



If anything in the text isn't a letter, ignore it and don't return it.



a being 1, b being 2, 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)









share|improve this question











$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













20












20








20


5



$begingroup$



If anything in the text isn't a letter, ignore it and don't return it.



a being 1, b being 2, 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)









share|improve this question











$endgroup$





If anything in the text isn't a letter, ignore it and don't return it.



a being 1, b being 2, 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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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












  • 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










5 Answers
5






active

oldest

votes


















25












$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)





share|improve this answer











$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 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$
    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



















9












$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)





share|improve this answer









$endgroup$




















    6












    $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 letters dictionary is constructed anew on every call of @alecxe's function, which is easy to change. (UPD.: no, not anymore). If that matters.






    share|improve this answer











    $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 that bytes( ... generate bytes ... ).encode('ascii') would be faster than calling str on each character.
      $endgroup$
      – wvxvw
      Dec 27 '17 at 6:23



















    6












    $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





    share|improve this answer











    $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


















    -1












    $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?





    share








    New contributor




    Tony Rayman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






    $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











    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
    );



    );













    draft saved

    draft discarded


















    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









    25












    $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)





    share|improve this answer











    $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 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$
      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
















    25












    $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)





    share|improve this answer











    $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 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$
      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














    25












    25








    25





    $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)





    share|improve this answer











    $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)






    share|improve this answer














    share|improve this answer



    share|improve this answer








    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 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$
      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$
      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$
      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$
    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














    9












    $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)





    share|improve this answer









    $endgroup$

















      9












      $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)





      share|improve this answer









      $endgroup$















        9












        9








        9





        $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)





        share|improve this answer









        $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)






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Dec 26 '17 at 18:36









        яүυкяүυк

        7,19122054




        7,19122054





















            6












            $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 letters dictionary is constructed anew on every call of @alecxe's function, which is easy to change. (UPD.: no, not anymore). If that matters.






            share|improve this answer











            $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 that bytes( ... generate bytes ... ).encode('ascii') would be faster than calling str on each character.
              $endgroup$
              – wvxvw
              Dec 27 '17 at 6:23
















            6












            $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 letters dictionary is constructed anew on every call of @alecxe's function, which is easy to change. (UPD.: no, not anymore). If that matters.






            share|improve this answer











            $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 that bytes( ... generate bytes ... ).encode('ascii') would be faster than calling str on each character.
              $endgroup$
              – wvxvw
              Dec 27 '17 at 6:23














            6












            6








            6





            $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 letters dictionary is constructed anew on every call of @alecxe's function, which is easy to change. (UPD.: no, not anymore). If that matters.






            share|improve this answer











            $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 letters dictionary is constructed anew on every call of @alecxe's function, which is easy to change. (UPD.: no, not anymore). If that matters.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            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 that bytes( ... generate bytes ... ).encode('ascii') would be faster than calling str 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$
              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$
            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












            6












            $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





            share|improve this answer











            $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















            6












            $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





            share|improve this answer











            $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













            6












            6








            6





            $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





            share|improve this answer











            $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






            share|improve this answer














            share|improve this answer



            share|improve this answer








            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












            • 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











            -1












            $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?





            share








            New contributor




            Tony Rayman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.






            $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
















            -1












            $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?





            share








            New contributor




            Tony Rayman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.






            $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














            -1












            -1








            -1





            $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?





            share








            New contributor




            Tony Rayman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.






            $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?






            share








            New contributor




            Tony Rayman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.








            share


            share






            New contributor




            Tony Rayman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.









            answered 5 hours ago









            Tony RaymanTony Rayman

            11




            11




            New contributor




            Tony Rayman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.





            New contributor





            Tony Rayman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.






            Tony Rayman is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.







            • 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




              $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


















            draft saved

            draft discarded
















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            名間水力發電廠 目录 沿革 設施 鄰近設施 註釋 外部連結 导航菜单23°50′10″N 120°42′41″E / 23.83611°N 120.71139°E / 23.83611; 120.7113923°50′10″N 120°42′41″E / 23.83611°N 120.71139°E / 23.83611; 120.71139計畫概要原始内容臺灣第一座BOT 模式開發的水力發電廠-名間水力電廠名間水力發電廠 水利署首件BOT案原始内容《小檔案》名間電廠 首座BOT水力發電廠原始内容名間電廠BOT - 經濟部水利署中區水資源局

            Prove that NP is closed under karp reduction?Space(n) not closed under Karp reductions - what about NTime(n)?Class P is closed under rotation?Prove or disprove that $NL$ is closed under polynomial many-one reductions$mathbfNC_2$ is closed under log-space reductionOn Karp reductionwhen can I know if a class (complexity) is closed under reduction (cook/karp)Check if class $PSPACE$ is closed under polyonomially space reductionIs NPSPACE also closed under polynomial-time reduction and under log-space reduction?Prove PSPACE is closed under complement?Prove PSPACE is closed under union?

            Is my guitar’s action too high? Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)Strings too stiff on a recently purchased acoustic guitar | Cort AD880CEIs the action of my guitar really high?Μy little finger is too weak to play guitarWith guitar, how long should I give my fingers to strengthen / callous?When playing a fret the guitar sounds mutedPlaying (Barre) chords up the guitar neckI think my guitar strings are wound too tight and I can't play barre chordsF barre chord on an SG guitarHow to find to the right strings of a barre chord by feel?High action on higher fret on my steel acoustic guitar