Python:当字符串发生变化时在字符串中循环

2024-10-01 13:38:12 发布

您现在位置:Python中文网/ 问答频道 /正文

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不能正确地加密替换密码,但是为什么python在第五行中抛出一个错误“substring not found”? 我不是在明文中迭代字符吗? 我使用的语言是python

谢谢!在


Tags: keytextinforindexreturndefch
2条回答

在你的代码中有几个问题导致它根本没有做你想做的事情。

1。字符串在Python中是不可变的

不能在Python中更改字符串。一旦它被创建,它就保持不变。 您所能做的就是创建一个新的字符串,可能基于原始字符串,然后 给它指定相同的名称。在

例如,可以使用切片表示法在某个索引处分配新元素,从而修改alist(可变类型):

>>> lst = ['one', 'two', 'three']
>>> lst[0] = 42
>>> lst
[42, 'two', 'three']

不能用字符串做到这一点,字符串是不可变的:

^{pr2}$

因此,您所能做的就是给s分配一个全新的字符串:

>>> s = s.upper()
>>> s
'ABC'

因此,upper(),就像replace()和所有其他字符串方法一样,在的地方不工作, 而是返回字符串的修改后的副本。在

关于原因,请参见Why are Python strings immutable?。基本上可以归结为性能。


2。循环不会迭代s。它迭代循环开始时s的值

执行for item in iterable操作时,Python将执行以下操作:

  • 它获取对iterable指向的值的引用(在循环的开始处)。
    • 如果该值是一个字符串,它将获得对该字符串的引用。既然你不能 修改字符串时,该引用将始终指向内存中的同一对象。在
    • 如果值是可变的(如列表),则引用将指向该值。在
  • 每次迭代,它从引用指向的iterable值中获取下一项。 如果这个值是可变的,同时又发生了变化,那么运气不好,你会得到奇怪的结果。在

3。你不应该在迭代可变序列时改变它们

即使str是一个可变类型,并且您可以更改它,也决不应该在迭代时更改iterable。在

示例:

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已经为这个目的提供了一个^{}函数(如@scar López的答案中所述),因此您应该使用这个函数。在

你不应该迭代那些同时被修改的东西(不管是列表,集合,还是字典…你明白了),而且字符串是不可变的,所以实际上每次迭代都要创建新的字符串。对于在Python中实现替换密码,没有什么比使用^{}更容易的了,而且我们可以使转换在两个方向上工作:

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'

相关问题 更多 >