80

How can the following be finished?

characters = ['a''b''c''d''e''f''g''h''i''j''k''l''m''n''o''p''q''r''t''u''v''w''x''y''z']
numbers = ['1''2''3''4''5''6''7''8''9''10''11''12''13''14''15''16''17''18''19''20''21''22''23''24']
text = raw_input(' Write text: ')

I've tried to solve it many ways, but couldn't get to the pint. I want to make exc. If I type "hello" the output to be in numbers lined like in alphabet. Example a = 1 < in alphabet.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
altin
  • 817
  • 2
  • 7
  • 4
  • 3
    What do you have so far, and how doesn't it work? – Ignacio Vazquez-Abrams Dec 25 '10 at 01:37
  • this one works : http://pastebin.com/SYwgcpg8 but when I grow the numbers it doesnt work, I dont know other ways :S – altin Dec 25 '10 at 01:39
  • 3
    Just a note, you miss one letter and two numbers in your list... :P You should always try to avoid building long lists like that by hand. There are better way to do that. :) (ex: import string; letters = string.lowercase) – Morlock Dec 25 '10 at 01:50
  • 3
    Those lists don't have commas. – razpeitia Dec 25 '10 at 02:27
  • 1
    What do you actually want for output, please show example? Because `'ab' == '12' == 'l'`. In your pastebin code maketrans takes a string of letters to letters mapping like 'abcd', '1234'. This won't support 2 digit numbers. – kevpie Dec 25 '10 at 07:43
  • You don't need to manually write the letters and their respective alphabets. You can write: `from string import ascii_lowercase` Then in another line - `LETTERS = {letter: str(index) for index, letter in enumerate(ascii_lowercase, start=1)}` – Dipen Gajjar Aug 24 '19 at 14:08

19 Answers19

109

What about something like this:

print [ord(char) - 96 for char in raw_input('Write Text: ').lower()]

ord
list comprehension
ASCII character codes

EDIT
Since you asked me to explain I will... though it has been explained pretty well in the comments already by [?].

Let's do this in more that one line to start.

input = raw_input('Write Text: ')
input = input.lower()
output = []
for character in input:
    number = ord(character) - 96
    output.append(number)
print output

This does the same thing, but is more readable. Make sure you can understand what is going on here before you try to understand my first answer. Everything here is pretty standard, simple Python. The one thing to note is the ord function. ord stand for ordinal, and pretty much every high level language will have this type of function available. It gives you a mapping to the numerical representation of any character. The inverse function of ord is called chr.

chr(ord('x')) == 'x' # for any character, not just x.

If you test for yourself, the ordinal of a is 97 (the third link I posted above will show the complete ASCII character set.) Each lower case letter is in the range 97-122 (26 characters.) So, if you just subtract 96 from the ordinal of any lower case letter, you will get its position in the alphabet assuming you take 'a' == 1. So, ordinal of 'b' == 98, 'c' == 99, etc. When you subtract 96, 'b' == 2, 'c' == 3, etc.

The rest of the initial solution I posted is just some Python trickery you can learn called list comprehension. But, I wouldn't focus on that as much as I would focus on learning to solve the problem in any language, where ord is your friend.

starball
  • 20,030
  • 7
  • 43
  • 238
sberry
  • 128,281
  • 18
  • 138
  • 165
  • 2
    wow this worked perfect thank you... I'm sorry if I bother you but Id be thankful if you'd explain the code to me :) – altin Dec 25 '10 at 02:01
  • @altin: `ord()` returns the integer ordinal of a character string. So `ord('A')` will return 97, the ASCII value for `A`. The `[]` is a list comprehension. It means, get the `ord` value of the character you inputted via `raw_input`, convert it to lower case using `.lower()` and subtract 96 from it. This is being done to get the output you desired. – user225312 Dec 25 '10 at 05:00
  • I don't know if this is supposed to be an issue, but any punctuation is going to give negative values. I would be tempted to add 'if char.isalpha()' to your list comprehension Cheers. – Morlock Dec 25 '10 at 15:08
  • 1
    Don't use magic numbers in your code. Instead of `96`, use `ord('a') - 1` for clarity. – qntm Feb 21 '14 at 11:57
48

You can use chr() and ord() to convert betweeen letters and int numbers.

Here is a simple example.

>>> chr(97)
'a'
>>> ord('a')
97
Statham
  • 4,000
  • 2
  • 32
  • 45
  • 7
    Code-only answers are very seldom helpful. Please explain how this answers the question. Thanks. – Ole V.V. Nov 26 '17 at 13:25
  • 10
    I disagree, I usually scroll down until I find a neat and short code answer to copy and paste while avoid reading long explanations – pcko1 Jun 22 '20 at 14:53
  • For ***Pandas*** I had to do: ```df['number_col'] = df['number_col'].astype(int).apply(lambda x: chr(ord('`')+x))``` – kevin_theinfinityfund Nov 05 '20 at 07:21
13

Not to be too basic, but this:

>>> char1 = ['a''b''c''d''e''f''g''h''i''j''k''l'
             'm''n''o''p''q''r''s''t''u''v''w''x''y''z']

is very different than this:

>>> char2 = ['a','b','c','d','e','f','g','h','i','j','k','l',
               'm','n','o','p','q','r','s','t','u','v','w','x','y','z']

The first, without commas and what you have in your question, is a one element list with a 26 element string. The second is a 26 element list each a single character in length.

If you print each:

>>> print char1, len(char1), len(char1[0])
['abcdefghijklmnopqrstuvwxyz'] 1 26
>>> print char2, len(char2), len(char2[0])
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 
'm', 'n', 'o', 'p', 'q','r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'] 26 1

It becomes apparent that it takes an additional step to turn the individual characters of char1 into an iterable.

If you have the sequence of characters 'a' through 'z' and/or 'A' through 'Z', you can easily return the number of the character with list comprehension:

>>> [ord(x)%32 for x in char2]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 
17, 18, 19, 20, 21, 22, 23, 24, 25, 26]

For the type of data structure you have, you need to access the string first:

>>> [ord(x)%32 for x in char1[0]]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 
17, 18, 19, 20, 21, 22, 23, 24, 25, 26]

So if your code listing is the same as in your question, that may be your issue.

A reasonable alternative is: [ord(x.lower())-96 for x in char1[0]]

You can see that your characters=['a''b''c'...], without the commas, is just the same as typing all the characters in a string in a list like this ['abc...'].

So now try:

 >>> import string
 >>> [ord(x.lower())-96 for x in string.letters]
 [1,2,...26, 1,2,3...26]      # my ellipses 
 >>> char3=[string.letters]   # one string as element[0]
 >>> [ord(x)%32 for x in char3[0]]
 >>> [ord(x)%32 for x in [string.letters][0]]
dawg
  • 98,345
  • 23
  • 131
  • 206
9

If you are going to use this conversion a lot, consider calculating once and putting the results in a dictionary:

>>> import string
>>> di=dict(zip(string.letters,[ord(c)%32 for c in string.letters]))
>>> di['c'] 
3

The advantage is dictionary lookups are very fast vs iterating over a list on every call.

>>> for c in sorted(di.keys()):
>>>    print "{0}:{1}  ".format(c, di[c])
# what you would expect....
the wolf
  • 34,510
  • 13
  • 53
  • 71
9

You can map the alphabet to a list and return the index of each one as per the below :

import string

alphabet=string.ascii_lowercase
#alphabet='abcdefghijklmnopqrstuvwxyz'

#Get the character index , ex: e  
print(chars.find('e'))
#This will return 4
Asser Yehia
  • 198
  • 2
  • 6
  • 2
    You certainly mean `alphabet.find`, not `chars.find`. Also shouldn't it be `chars.find('e') + 1`? Just to mention that. – colidyre Apr 07 '20 at 02:51
  • 2
    While this code may solve the question, including an explanation of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please edit your answer to add explanations and give an indication of what limitations and assumptions apply. You may want to take a look at [answer]. – mmgross Apr 07 '20 at 07:47
6

This is a function I used to use for this purpose. Works for both uppercase and lowercase.

def convert_char(old):
    if len(old) != 1:
        return 0
    new = ord(old)
    if 65 <= new <= 90:
        # Upper case letter
        return new - 64
    elif 97 <= new <= 122:
        # Lower case letter
        return new - 96
    # Unrecognized character
    return 0
parent5446
  • 898
  • 7
  • 17
  • 1
    Since you bring everyone (uppercase and lowercase) to numbers, I would rather convert your 'old' to lowercase rather than making 2 separate cases (if and elif). +1 :) – Morlock Dec 25 '10 at 01:53
  • is there any raw_input('text: ') ? – altin Dec 25 '10 at 01:54
  • Yeah, @Morlock is right. This code is pretty old and I don't think I even wrote all of it (just copied and pasted from source). @sberry2A might actually have the best solution. – parent5446 Dec 25 '10 at 03:56
6

Something like this

[str(ord(c)&31) for c in text]
Community
  • 1
  • 1
Kabie
  • 10,489
  • 1
  • 38
  • 45
4
def letter_to_int(letter):
    alphabet = list('abcdefghijklmnopqrstuvwxyz')
    return alphabet.index(letter) + 1

here, the index (x) function returns the position value of x if the list contains x.

Nikolay Kostov
  • 16,433
  • 23
  • 85
  • 123
ehfgk78
  • 41
  • 1
4
>>> [str(ord(string.lower(c)) - ord('a') + 1) for c in string.letters]
['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17',
'18', '19', '20', '21', '22', '23', '24', '25', '26', '1', '2', '3', '4', '5', '6', '7', '8',
'9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24',
 '25', '26']
moinudin
  • 134,091
  • 45
  • 190
  • 216
3

Here's something I use to convert excel column letters to numbers (so a limit of 3 letters but it's pretty easy to extend this out if you need more). Probably not the best way but it works for what I need it for.

def letter_to_number(letters):
    letters = letters.lower()
    dictionary = {'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}
    strlen = len(letters)
    if strlen == 1:
        number = dictionary[letters]
    elif strlen == 2:
        first_letter = letters[0]
        first_number = dictionary[first_letter]
        second_letter = letters[1]
        second_number = dictionary[second_letter]
        number = (first_number * 26) + second_number
    elif strlen == 3:
        first_letter = letters[0]
        first_number = dictionary[first_letter]
        second_letter = letters[1]
        second_number = dictionary[second_letter]
        third_letter = letters[2]
        third_number = dictionary[third_letter]
        number = (first_number * 26 * 26) + (second_number * 26) + third_number
    return number
  • I've been looking for something like that and found that there are already functions for this one https://xlsxwriter.readthedocs.io/working_with_cell_notation.html#cell-utility – madlymad Feb 24 '19 at 12:59
3
characters = 'abcdefghijklmnopqrstuvwxyz'
d = {}
for x in range(len(characters)):
    d[characters[x]] = x+1

print(d)

prints {'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}

print(d['a']) # 1
print(d['z']) # 26
2

If you are just looking to map a number to a letter, then just do something simple like this:

def letter_to_index(letter):
    _alphabet = 'abcdefghijklmnopqrstuvwxyz'
    return next((i for i, _letter in enumerate(_alphabet) if _letter == letter), None)

Of course if you want to have it start at 1, then just add (i+1 for i, ... etc.

regularex
  • 21
  • 5
2

If you are looking the opposite like 1 = A , 2 = B etc, you can use the following code. Please note that I have gone only up to 2 levels as I had to convert divisions in a class to A, B, C etc.

loopvariable = 0 
    numberofdivisions = 53
    while (loopvariable <numberofdivisions):
        if(loopvariable<26):
            print(chr(65+loopvariable))
        loopvariable +=1
        if(loopvariable > 26 and loopvariable <53):
            print(chr(65)+chr(65+(loopvariable-27)))
2

Use this function. It converts a string of alphabet to its equivalent digit value:

def convAlph2Num(sent):
    alphArray = list(string.ascii_lowercase)
    alphSet = set(alphArray)
    sentArray = list(sent.lower())
    x = []
    for u in sentArray:
        if u in alphSet:
            u = alphArray.index(u) + 1
            x.append(u)
    print(x)
    return
t j
  • 7,026
  • 12
  • 46
  • 66
dabire
  • 65
  • 7
1

If the goal is to transform only the letters abcd....xyz and ABCD....XYZ , I would use a function:

from string import letters
def rank(x, d = dict((letr,n%26+1) for n,letr in enumerate(letters[0:52]))):
    return d[x]

I’ve written [0:52] because my Python 2.7 version displays the value

*ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz*ƒŠŒŽšœžŸÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ

for the string.letters argument.

Because the parameter d receives a value as a default argument, the calculus of this value is performed only once, at the moment when the definition of the function is executed to produce the function object. So, the function can then be used without this value to be calculated again, even if the function is appealed three thousand times.

By the way, lower() isn’t used again for each appeal of the function. The case of upper letters has been treated during the construction of the default argument.

.

One example of use:

word = 'supercalifragilisticexpialidocious'
print ''.join( letter if rank(letter)%3!=0 else '.' for letter in word)

result:

s.pe..a....ag...st..e.p.a..d.....s

.

It can be used with map() too :

print map(rank,'ImmunoElectroPhoresis')

result:

[9, 13, 13, 21, 14, 15, 5, 12, 5, 3, 20, 18, 15, 16, 8, 15, 18, 5, 19, 9, 19]

eyquem
  • 26,771
  • 7
  • 38
  • 46
1
import string
# Amin
my_name = str(input("Enter a your name: "))
numbers      = []
characters   = []
output       = []
for x, y in zip(range(1, 27), string.ascii_lowercase):
    numbers.append(x)
    characters.append(y)

print(numbers)
print(characters)
print("----------------------------------------------------------------------")

input = my_name
input = input.lower()

for character in input:
    number = ord(character) - 96
    output.append(number)
print(output)
print("----------------------------------------------------------------------")

sum = 0
lent_out = len(output)
for i in range(0,lent_out):
    sum = sum + output[i]

print("resulat sum is : ")
print("-----------------")

print(sum)





resualt is :
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
----------------------------------------------------------------------
[1, 13, 9, 14]
----------------------------------------------------------------------
resulat sum is : 
-----------------
37
Amin
  • 342
  • 4
  • 15
  • Ideally you would want to count spaces because this program isn't a demonstration of ascii its a functioning calculator for possible encryption schemes. you would be able to enter " words from the crytography section of the news paper and also figure them out too. " the number siphering is always interesting because some coded messages start with 1 = z, y =2, " --- A26 so on and so fourth – Fred Collins Feb 01 '23 at 05:27
  • so at the end Results should be: Words = 2 value of word " app " = 33 value of word" be " = 7 character count = 5 – Fred Collins Feb 01 '23 at 05:28
1

This is very simple script to do what you are asking for ! try this:

#!/usr/bin/env python3

def remove(string): 
    return string.replace(" ", "")

dict = {'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',
}

word = remove(input(''))

for x in word:
    print(dict[x])

## or ##
#index = 0
#for x in word:
#   print(dict[word[index]])
#   index = index + 1
kh.waeli
  • 21
  • 2
  • Please explain what your code does and how it does it. – M-Chen-3 Dec 07 '20 at 16:50
  • 1
    @M-Chen-3 my code does exactly what #altin wanted in his question and that is convert letters to numbers. The defined function at the beginning of my code is to remove space from the text that you will insert because space is counted as index. then I made 'for loop' to convert each index in the inserted text to the corresponding number listed in the variable 'dict'. – kh.waeli Dec 08 '20 at 07:36
0

Performing AND operation with the number 31 on the letters would work.

Here is an example:

str1 = 'abcdefABCDEF'
list1 = []

for i in str1:
    list1.append(ord(i) & 31)
print(list1)

for j in range(0, len(list1)):
    print(chr(list1[j] + 64), end = '')

The result of this would be:

[1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]
ABCDEFABCDEF
0

This was my solution quite some time ago, when client wanted code number based on city where specific product was made. Juice, made in Alabama would be 252 while the same juice made in Kleveland would be 553.

def letter_to_number(letters):
letters = letters.lower()
let_dict = {
    "a": 2,
    "b": 2,
    "c": 2,
    "d": 3,
    "e": 3,
    "f": 3,
    "g": 4,
    "h": 4,
    "i": 4,
    "j": 5,
    "k": 5,
    "l": 5,
    "m": 6,
    "n": 6,
    "o": 6,
    "p": 7,
    "q": 7,
    "r": 7,
    "s": 7,
    "t": 8,
    "u": 8,
    "v": 8,
    "w": 9,
    "x": 9,
    "y": 9,
    "z": 9,
}
first_letter = letters[0]
number1 = let_dict[first_letter]
second_letter = letters[1]
number2 = let_dict[second_letter]
third_letter = letters[1]
number3 = let_dict[third_letter]
number = f"" + str(number1) + str(number2) + str(number3) + ""
end_number = int(number)
return end_number 
  • The answer isn't a universal solution. Using your example, juice from Portland and juice from Portsmouth would have the same ID. A complete solution will require more thought. – Laughing Vergil Feb 16 '23 at 04:36