我想要仅打印字母,但它会打印ASCII的特殊字符。我的代码:
import string
def caesar(shift):
alphabet = string.ascii_lowercase + string.ascii_uppercase
dict={}
emptylist=[]
int(shift)
for x in alphabet:
emptylist.append(x)
code = ""
for letters in emptylist:
code = chr(ord(letters) + shift)
dict[letters]=code
return dict
caesar(12)
我的输出:
'm':'y','l':'x','o':'{','n':'z','q':'}','p':'|' ,'s':'\ x7f','r':'〜','u':'\ x81','t':'\ x80','w':'\ x83','v':' \ x82','y':'\ x85','x':'\ x84','z':'\ x86'
正确输出:
'm':'y','l':'x','o':'a','n':'z','q':'c','p':'b' ,'s':'e','r':'d','你':'g','t':'f','w':'我','v':'h',' y':'k','x':'j','z':'l'
答案 0 :(得分:5)
使用ord()
并更改字符代码不会将结果字符限制在字典中。
我只是找到字典中的字母索引,移动它,并使用模运算符:
import string
def caesar(shift):
alphabet = string.ascii_uppercase # <- Change it back to what you had before
# and see what will happen.
mapping = {}
for letter in alphabet:
index = alphabet.index(letter)
mapping[letter] = alphabet[(index + shift) % len(alphabet)]
return mapping
测试(字典不保留顺序,因此很难阅读):
>>> caesar(12)
{'A': 'M', 'C': 'O', 'B': 'N', 'E': 'Q', 'D': 'P', 'G': 'S', 'F': 'R', 'I': 'U', 'H': 'T', 'K': 'W', 'J': 'V', 'M': 'Y', 'L': 'X', 'O': 'A', 'N': 'Z', 'Q': 'C', 'P': 'B', 'S': 'E', 'R': 'D', 'U': 'G', 'T': 'F', 'W': 'I', 'V': 'H', 'Y': 'K', 'X': 'J', 'Z': 'L'}
答案 1 :(得分:5)
让我们特别看一个错误:o: '{'
。
请注意ord('o')
为111,所以让我们看看chr
中的range(111,130)
整数:
从o
开始,移动12,将您带到{
字符:
In [75]: ' '.join([chr(x) for x in range(111,130)])
Out[75]: 'o p q r s t u v w x y z { | } ~ \x7f \x80 \x81'
^ 1 2 3 4 5 6 7 8 9 ...12
所以你输出错误的原因是因为你的公式
code = chr(ord(letters) + shift)
没有考虑如果班次让您退出与a-z
或A-Z
相关联的行列会发生什么。 (请注意,a-z
和A-Z
的ord范围也不是连续的!)
以下是如何修复的提示:
In [82]: alphabet = string.ascii_lowercase + string.ascii_uppercase
In [83]: alphabet.index('o')
Out[83]: 14
In [84]: alphabet[alphabet.index('o')+12]
Out[84]: 'A'
但
In [85]: alphabet[alphabet.index('O')+12]
结果为IndexError: string index out of range
。那是因为len(alphabet)
是52,而
In [91]: alphabet.index('O')+12
Out[91]: 52
不知怎的,我们需要52回绕到0.您可以使用%
modulo operator:
In [92]: 52 % 52
Out[92]: 0