如何在Python3上更改字符串i' m for-looping的值

时间:2016-10-31 17:21:52

标签: python

我试图实施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"。问题是什么?

4 个答案:

答案 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