主要规则是:在迭代列表时不要修改列表,但是...
给出以下代码以删除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']
如果在循环内修改列表,迭代器在迭代时不会丢失的情况如何?我希望这会导致错误或行为不一致。
答案 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;