def substitutionEncrypt1(text,key):
plaintext=text.lower()
alphabet="abcdefghijklmnopqrstuvwxyz "
for ch in plaintext:
r=plaintext.index(ch)
plaintext=plaintext.replace(ch,key[r])
return plaintext
我的文字是"快速布朗福克斯" 我理解为什么它没有正确地加密替换密码,但为什么python在第五行中抛出一个错误,说" substring not found"? 我不是在明文中迭代字符吗? 我使用的语言是python
谢谢!
答案 0 :(得分:1)
您的代码中存在一些问题,这些问题使其无法满足您的需求。
您无法在Python中更改字符串。一旦它被创建,它就会保持不变。 你所能做的就是创建一个新的字符串,可能是基于原始字符串,和 将它指定为相同的名称。
例如,您可以通过使用切片表示法在某个索引处分配新元素来修改 list
(一种可变类型):
>>> lst = ['one', 'two', 'three']
>>> lst[0] = 42
>>> lst
[42, 'two', 'three']
你不能用字符串来做,它们是不可变的:
>>> s = 'abc'
>>> s[1] = 42
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
因此,您所能做的就是为s
分配一个全新的字符串:
>>> s = s.upper()
>>> s
'ABC'
因此,upper()
,如replace()
和所有其他字符串方法, in-place 不起作用,
它改为返回字符串的修改后的副本。
至于原因,请参阅Why are Python strings immutable?。它基本上归结为性能。
s
。它迭代循环开始时的值s
。执行for item in iterable
时,这就是Python的作用:
iterable
指向的值(在循环开始时)。
即使str
是一个可变类型,并且你可以更改它,你也不应该在迭代迭代时更改迭代。
示例:
lst = [1, 2, 3, 4, 5]
for item in lst:
print item,
lst.remove(item)
输出:
1 3 5
如您所见,已跳过项目,因为在迭代期间列表大小和项目的相应索引已更改。
对于词典,Python甚至会明确地警告你,并拯救:
dct = dict(foo=23, bar=42)
for key in dct:
print key
dct['baz'] = 'qux'
输出:
foo
Traceback (most recent call last):
File "it.py", line 3, in <module>
for key in dct:
RuntimeError: dictionary changed size during iteration
所以,记住这一切,如果你 以你想要的方式实现你的代码,你需要 保持两个变量彼此分开,一个是你循环的,一个是你将翻译后的结果分配给。
但是,由于Python已经具有translate()
功能(正如@ÓscarLópez的回答中所解释的那样),正是出于这个目的,这就是你应该使用的。
答案 1 :(得分:0)
你不应该迭代某些东西(无论是列表,集合,还是字典......你明白了)同时被修改 - 而且,字符串是不可变的,所以在现实你在每次迭代时创建新的字符串。为了在Python中实现替换密码,没有什么比使用translate()
更容易了 - 我们可以使翻译在两个方向上工作:
import string
alphabet = 'abcdefghijklmnopqrstuvwxyz '
subst = 'edbjvushlpknyxt foqiwacrzgm'
table = string.maketrans(alphabet, subst)
'hello world'.translate(table)
=> 'hvnntmctonj'
table = string.maketrans(subst, alphabet)
'hvnntmctonj'.translate(table)
=> 'hello world'