【问题标题】:Python iterator unexpected behavior while modifying its list inside a for-in loopPython迭代器在for-in循环内修改其列表时出现意外行为
【发布时间】:2019-04-04 14:01:03
【问题描述】:

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

给定以下代码来删除 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']

如果列表在循环内被修改,迭代器如何在迭代时不会丢失?我预计这会产生错误或不一致的行为。

【问题讨论】:

    标签: python-3.x iterator


    【解决方案1】:

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

    您可以在以下位置查看列表对象的 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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-07
      相关资源
      最近更新 更多