python - 为什么我不能更改正在迭代的集合?

标签 python

我看到了建议的解决方案和变通方法,但找不到关于不允许在遍历集合时更改集合的选择的解释。 你能帮我理解为什么这样可以吗

In [1]: l = [1]

In [2]: for i in l:
            l.append(2*i)
            if len(l)>10:
                    break

In [3]: l
Out[3]: [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]

虽然这样不行

In [4]: l = {1}

In [5]: for i in l:
            l.add(2*i)
            if len(l)>10:
                    break
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-5-b5bdff4a382b> in <module>()
----> 1 for i in l:
      2         l.add(2*i)
      3         if len(l)>10:
      4                 break
      5

RuntimeError: Set changed size during iteration

在迭代时更改集合有什么不好?

我知道 set 中的顺序未定义,因此 next 可能会遇到困难。是这个原因吗?

最佳答案

集合由哈希表 支持(参见 Why is the order in Python dictionaries and sets arbitrary? )。集合中的条目根据它们的哈希值被放入该表中,而哈希值又决定了它们的顺序。

向该哈希表中添加或删除项目将改变迭代顺序,有时会因为可以重新调整表的大小而发生重大变化(所有现有条目都根据新表的大小重新分配) .因为这个迭代不能在集合被改变的那一刻继续;否则您可能会再次看到相同的值,即使顺序不同也是如此。

另一方面,列表具有明确定义的顺序。插入或删除项目可以改变该顺序,但以明确定义的方式进行。因此,列表迭代器可以简单地使用不断增加的索引来查找“下一个”项目,直到该索引与当前列表长度匹配。

关于python - 为什么我不能更改正在迭代的集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38422997/

相关文章:

python - 读取文件中途停止

python - 从 python 脚本导入 shell 变量

python - 使用编码打开内存映射文件

命令提示符中未显示 Python 版本

python total_ordering : why __lt__ and __eq__ instead of __le__?

python - 如何在 python 中检查文件是否关闭?

python - 如何使用 pandas 行形成新列

python - 使用 "does not contain"一对多过滤 SQLAlchemy

python - 在 python 交互式 shell 中实现类似于 "help"命令的类似操作

python - 为什么正则表达式不起作用?