Python:当字符串发生变化时,循环遍历字符串中的字符

时间:2014-07-27 15:52:48

标签: python string loops

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

谢谢!

2 个答案:

答案 0 :(得分:1)

您的代码中存在一些问题,这些问题使其无法满足您的需求。

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

您无法在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?。它基本上归结为性能。


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

执行for item in iterable时,这就是Python的作用:

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

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

即使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'