在 python 中动态更改迭代器是否安全?

pro*_*eek 3 python iteration

使用 python,我需要在迭代列表时动态添加列表中的成员:

i = [1,2,3,4,5]

for a in i:
    if a == 1:
        i.append(100)
    print a
Run Code Online (Sandbox Code Playgroud)

能保证正常工作吗?

Mar*_*ers 6

您正在更改序列,而不是迭代器。循环for调用iter()要循环的对象,创建循环迭代器。对于list对象,创建的列表迭代器保留对原始列表和内部索引的引用,每次循环for请求下一个项目(调用next()迭代器)时,都会返回当前索引处的项目,并且索引会递增。

这种情况下,它是安全的,因为循环迭代器对象将愉快地继续处理额外的项目。只要您不i无限期地添加项目,循环就会完成。

但是,如果您要从中删除项目i,则循环迭代器将看不到这些更改,并且您将得到“令人惊讶”的结果:

i = [1, 2, 3, 4, 5]
for a in i:
   if a == 1:
       del i[0]
   print a
Run Code Online (Sandbox Code Playgroud)

印刷:

1
3
4
5
Run Code Online (Sandbox Code Playgroud)

因为循环迭代器i[1]在下一次迭代中产生,即 now 3,而不是2

如果要在当前迭代索引之前插入项目,也会出现类似的问题。

您可以自己创建迭代器,并手动进行实验以查看会发生什么:

>>> i = [1, 2, 3, 4, 5]
>>> i_iter = iter(i)  # index starts at 0
>>> next(i_iter)      # now the index is 1
1
>>> del i[0]
>>> i
[2, 3, 4, 5]          # item at index 1 is 3
>>> next(i_iter)      # returns 3, next index is 2
3
>>> i.insert(0, 1)
>>> i
[1, 2, 3, 4, 5]       # item at index 2 is 3
>>> next(i_iter)      # returns 3, next index is 3
3
Run Code Online (Sandbox Code Playgroud)