Python ord() 和 chr()

问题描述

我有

txt = input('What is your sentence? ')  
list = [0]*128
for x in txt:
    list[ord(x)] += 1
for x in list:
        if x >= 1:
            print(chr(list.index(x)) * x)

根据我的理解,这应该只输出一个句子中的每个字母,如:

))
111
3333
etc.

对于字符串 "aB)a2a2a2)" 输出是正确的:

))
222
B
aaaa

对于字符串 "aB)a2a2a2" 的输出错误的:

)
222
)
aaaa

我觉得我所有的基础都被覆盖了,但我不确定这段代码有什么问题。

解决方法

当您执行 list.index(x) 时,您在列表中搜索该值出现的第一个索引。不过,这实际上并不是您想要的,您需要刚刚读取的值的特定索引,即使相同的值也出现在列表中较早的其他位置。

从序列中沿边值获取索引的最佳方法是使用 enuemerate

for i,x in enumerate(list):
    if x >= 1:
        print(chr(i) * x)

这应该能让你得到你想要的输出,但还有其他一些事情可以让你的代码更容易阅读和理解。首先,使用 list 作为变量名是一个非常糟糕的主意,因为这会影响命名空间中内置的 list 类型的名称。这让任何阅读您代码的人都感到非常困惑,如果您想出于某种目的使用普通的 list 并且不记得您已经将它用于您自己的变量,您甚至会感到困惑。

另一个问题也是关于变量名,但它更微妙一些。您的两个循环都使用名为 x 的循环变量,但每次的值的含义都不同。第一个循环遍历输入字符串中的字符,而后一个循环遍历每个字符的计数。使用有意义的变量会让事情变得更清晰。

这是我建议的所有修复的组合:

text = input('What is your sentence? ')  
counts = [0]*128

for character in text:
    counts[ord(character)] += 1

for index,count in enumerate(counts):
        if count >= 1:
            print(chr(index) * count)