在Python中将字母转换为数字

80
以下内容如何完成?
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: ')

我已经尝试了很多方法,但都无法解决问题。我想制作一个程序。如果我输入"hello",输出应该是像字母表一样的数字行。例如,在字母表中a = 1。


3
你目前有什么进展,它有什么问题? - Ignacio Vazquez-Abrams
这个可以工作: http://pastebin.com/SYwgcpg8但是当我增加数字时,它无法工作,我不知道其他的方法。 :S - altin
3
注意,你的列表中漏掉了一封信和两个数字... :P 你应该尽量避免手动构建那样长的列表。有更好的方法可以做到这一点。 :) (例如:import string; letters = string.lowercase) - Morlock
3
这些列表没有逗号。 - razpeitia
1
你实际想要什么输出?请举个例子。因为 'ab' == '12' == 'l'。在你的 pastebin 代码中,maketrans 接受一个字母到字母映射的字符串,例如 'abcd'、'1234'。这不支持两位数。 - kevpie
你不需要手动编写字母及其对应的字母表。你可以这样写:from string import ascii_lowercase然后在另一行中 -LETTERS = {letter: str(index) for index, letter in enumerate(ascii_lowercase, start=1)} - Dipen Gajjar
19个回答

109

这个怎么样:

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

ord函数
列表推导式
ASCII字符编码

编辑
由于您要求我解释一下,尽管已经有[?]的评论对此进行了很好的解释。

让我们从多行开始。

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

这个代码做的事情和我的第一个答案一样,但是更易读。在试图理解我的第一个答案之前,请确保你能理解这里正在发生什么。这里的所有内容都是非常标准、简单的Python代码。需要注意的唯一一件事就是 ord 函数。ord代表序数,几乎所有高级语言都会提供这种类型的函数。它为任何字符提供了数字表示的映射。 ord 的反函数称为 chr。

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

如果你自己测试一下,你会发现'a'的序号是97(我在上面第三个链接中显示了完整的ASCII字符集)。每个小写字母都在范围97-122之间(26个字符)。因此,如果你从任何小写字母的序号中减去96,你将得到它在字母表中的位置,假设你认为'a'==1。所以,'b'的序号==98,'c'==99,等等。当你减去96时,'b'==2,'c'==3等。

我最初发布的解决方案的其余部分只是一些你可以学习的Python技巧,称为列表推导式。但是,我不会把重点放在这上面,而是把重点放在学习用任何语言解决问题上,其中ord是你的好朋友。


2
哇,这个完美地运行了,谢谢你... 如果我打扰到你了,不好意思,但如果你能向我解释一下代码,我会很感激的 :) - altin
@altin:ord()返回字符字符串的整数序数。因此,ord('A')将返回97,即A的ASCII值。[]是列表推导式。它的意思是,获取通过raw_input输入的字符的ord值,使用.lower()将其转换为小写,并从中减去96。这样做是为了获得您所需的输出。 - user225312
我不知道这是否应该是一个问题,但任何标点符号都会给出负值。我会倾向于在您的列表理解中添加'if char.isalpha()'。干杯。 - Morlock
1
在你的代码中不要使用魔法数字。为了清晰明了,应该使用ord('a') - 1代替96 - qntm

48

您可以使用 chr() 和 ord() 在字母和整数之间进行转换。

这里是一个简单的例子。

>>> chr(97)
'a'
>>> ord('a')
97

7
仅有代码的答案很少有帮助,请解释一下这个答案如何回答问题。谢谢。 - Ole V.V.
10
我不同意,我通常会滚动屏幕直到找到一个简洁明了的代码答案以供复制粘贴,同时避免阅读冗长的解释。 - pcko1
对于 Pandas,我需要执行以下操作: df['number_col'] = df['number_col'].astype(int).apply(lambda x: chr(ord('`')+x)) - kevin_theinfinityfund

13

不想太基础,但这个:

>>> 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']

这与下面的内容非常不同:

>>> 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']

第一个没有逗号和你在问题中提到的内容,它是一个包含一个26个元素字符串的单元素列表。第二个是一个包含26个单个字符的元素列表。
如果您打印每个:
>>> 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

很明显,将char1的各个字符转换为可迭代对象需要额外的步骤。
如果您有由字符'a'到'z'和/或'A'到'Z'组成的序列,可以轻松地使用列表推导式返回每个字符的编号。
>>> [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]

针对您所拥有的数据结构类型,您需要首先访问字符串:

>>> [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]

如果您的代码清单与您的问题中的相同,那可能就是您的问题所在。

一个合理的替代方案是:[ord(x.lower())-96 for x in char1[0]]

您可以看到,您的characters=['a''b''c'...],没有逗号,就像在列表中输入字符串中所有字符一样,例如 ['abc...']

现在请尝试:

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

9

您可以将字母表映射到一个列表,并根据以下方式返回每个字母的索引:

import string

alphabet=string.ascii_lowercase
#alphabet='abcdefghijklmnopqrstuvwxyz'

#Get the character index , ex: e  
print(chars.find('e'))
#This will return 4

2
你一定是指 alphabet.find,而不是 chars.find。另外,应该是 chars.find('e') + 1吧?只是提一下。 - colidyre
2
虽然这段代码可能解决了问题,但是加上解释为什么以及如何解决问题会真正有助于提高您的帖子质量,并且可能会得到更多的赞。请记住,您正在回答未来读者的问题,而不仅仅是现在提问的人。请编辑您的答案以添加解释并指出适用的限制和假设。您可能需要查看[答案]。 - mmgross

9

如果您要频繁使用此转换,请考虑计算一次并将结果放入字典中:

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

优点是字典查找非常快,而不是在每次调用时迭代列表。
>>> for c in sorted(di.keys()):
>>>    print "{0}:{1}  ".format(c, di[c])
# what you would expect....

6

这是我曾经用来实现此目的的函数。适用于大小写字母。

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

1
既然你把所有人(大写和小写)都转换成数字,我宁愿将你的“old”转换为小写,而不是制作两个单独的情况(if和elif)。+1 :) - Morlock
有没有 raw_input('text: ') ? - altin
是的,@Morlock 是对的。这段代码相当老了,我甚至不认为我写了全部(只是从源代码中复制和粘贴)。@sberry2A 可能有最好的解决方案。 - parent5446

6

类似于这个的东西。

[str(ord(c)&31) for c in text]

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']

4
def letter_to_int(letter):
    alphabet = list('abcdefghijklmnopqrstuvwxyz')
    return alphabet.index(letter) + 1

在这里,索引(x)函数返回x在列表中的位置值(如果列表包含x)。


3

以下是我用来将Excel列字母转换为数字的方法(最多只能处理3个字母,但如果需要更多,很容易扩展)。可能不是最好的方法,但对于我的需求来说,它有效。

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

我一直在寻找类似的东西,发现已经有这个功能了 https://xlsxwriter.readthedocs.io/working_with_cell_notation.html#cell-utility - madlymad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接