我试图实施Caesar的Cipher,它通过给定的密钥来抵消任何字母(例如,如果密钥是2,那么' a'变为' c&# 39)。
这是我的代码:
key = 2
code = "abc def hi"
code_splitted = code.split()
for word in code_splitted:
for char in word:
char = chr(ord(char) + key)
print (" ".join(code_splitted))
然而,输入是相同的代码" abc def hi"。问题是什么?
答案 0 :(得分:1)
python中的foreach循环提供了它在提供的iterable中找到的项的副本。这意味着当您更改'char'时,您实际上并未更改字符串中的数据。以下可能是您想要的:
for i in range(len(code_splitted)):
for j in range(len(code_splitted[i])):
code_splitted[i][j] = code_splitted[i][:j] + chr(ord(code_splitted[i][j]) + key) + code_splitted[i][j+1:]
当你这样做时,所有的更改都直接发生在原始数组中,而不是在python中创建的副本。
编辑:忘记字符串是不可变的,固定的代码。
答案 1 :(得分:1)
您无法修改项目,您正在修改副本/尝试更改不可变对象。
那就是说,最好的方法是使用2个嵌套的生成器理解构造:
key = 2
code = "abc def hi"
code_splitted = code.split()
code_splitted = ("".join(chr(ord(char) + key) for char in word) for word in code_splitted)
print (" ".join(code_splitted))
结果:
cde fgh jk
请注意,没有创建临时列表,因此性能更好,更pythonic(不涉及索引)
答案 2 :(得分:0)
如果您运行此选项并检查char
,您将看到您一直在更新该对象,但不会更新您最初引用的对象。您可以创建一个临时空白字符串并将新密钥串起来,并将其添加到列表中。
以下代码维护您的代码:
key = 2
code = "abc def hi"
newcode=[]
code_splitted = code.split()
for word in code_splitted:
tempcode = ''
for char in word:
tempcode += chr(ord(char) + key)
newcode.append(tempcode)
print (" ".join(newcode))
答案 3 :(得分:0)
这也可以通过替换您遇到的每个单词并将其附加到临时数组new_code
并打印答案来完成
import string
key = 2
code = "abc def hi"
new_code = []
for alpha in code:
if alpha.strip():
replaced = chr(ord(alpha) + key)
new_code.append(replaced)
else:
new_code.append(alpha)
print ''.join(new_code)
>>> cde fgh jk