Python迭代器在for-in循环内修改其列表时发生意外行为

时间:2018-10-31 11:54:50

标签: python-3.x iterator

主要规则是:在迭代列表时不要修改列表,但是...

给出以下代码以删除python列表中的特定元素(但有意写为循环):

mylist = ['a', 'b', 'c', 'd', 'e', 'f']

for i in mylist:
    if i == 'c':
        mylist.remove(i)

print(mylist)

>> ['a', 'b', 'd', 'e', 'f']

如果在循环内修改列表,迭代器在迭代时不会丢失的情况如何?我希望这会导致错误或行为不一致。

1 个答案:

答案 0 :(得分:0)

列表迭代器(其他迭代器的行为可能有所不同)的工作方式是记住它们当前位于哪个索引,当您下次调用时,它会检查索引是否在范围内,如果是,则获取一个项,然后更新索引。您的代码到达索引2,删除'c',然后转到索引3,该索引现在为'e'条目,并继续进行,完全跳过了'd'条目。如果在for循环中添加打印语句,则会看到该行为。

您可以在以下位置查看列表对象的C源代码:

https://github.com/python/cpython/blob/master/Objects/listobject.c

查找“ listiter_next”以查看实现。

它检查当前索引是否小于列表的长度:

if (it->it_index < PyList_GET_SIZE(seq))

,如果是,则获取该项并增加索引:

item = PyList_GET_ITEM(seq, it->it_index);
++it->it_index;