这里我们在循环时修改字符串s
:
s = 'hello'
for c in s:
s += c
print(s)
它不会生成无限循环(它可以:我们在每次迭代中添加一个新字符!)。
我已经知道了多年,但是我无法真正解释原因。这与字符串不变性有关还是无关紧要?
执行for c in s:
时,是否在开始循环之前将原始 s
复制到内存中?
我认为另一种情况可能会产生无限循环,但不会:
s = 'hello'
def f(x):
i = 0
while True:
try:
yield x[i]
except IndexError:
break
i += 1
for c in f(s):
s += c
print(s)
这不是递归方法。很好。它只会运行一次,因为您传递了一个字符串f('hello')
,现在循环中有“ hello”可以进行迭代。因此它将只运行一次
它不会产生无限循环(它可以:我们在每次迭代中添加一个新字符!)。
这是因为Python中的strings是不可变的。当您执行for c in s
时,for循环使用存储在变量s
中的引用绑定到对象,而当您执行s += c
时,您基本上是在创建一个新字符串,因此,您不会修改用于循环正在使用。
在https://docs.python.org/3/reference/compound_stmts.html#the-for-statement中ir说:
“循环修改序列时有一个微妙之处(这仅适用于可变序列,例如列表)。内部计数器用于跟踪下一个要使用的项目,并且在每个计数器上递增当计数器达到序列的长度时,循环终止。这意味着,如果套件从序列中删除当前(或上一个)项目,则下一个项目将被跳过(因为它获取了当前的索引)同样,如果套件在当前项目之前在序列中插入一个项目,则下次通过循环再次处理当前项目。”
因此,是的,Python将考虑原始字符串(如果内容更改,则主要是大小和位置)。但是,如果您更改了在for循环期间需要访问的字符,则可能会出现“令人惊讶”的行为。