You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python字典异常行为:不同版本循环修改字典的输出差异原因

为什么Python 2.7和3.6执行这段代码的输出不同?

这个问题的核心在于Python不同版本中字典的内部实现和迭代器逻辑的差异,咱们分版本拆解:

Python 2.7的行为原因

  • Python2.7的字典底层是传统哈希表结构,迭代器会直接遍历哈希表的所有槽位(bucket)。初始创建{0: None}时,字典的默认哈希表大小是8(共8个槽位)。
  • 循环中每次执行del d[i]删除当前键,再d[i+1] = None添加新键:因为整数的哈希值等于自身,新键i+1会刚好落在哈希表的第i+1个槽位。
  • 迭代器会逐个检查每个槽位,只要槽位里有键就会处理它。由于每次处理后新键都落在下一个未被检查的槽位,迭代器会一直遍历完所有8个槽位,直到槽位7处理完成后,没有更多槽位可遍历,循环结束。所以输出是0 1 2 3 4 5 6 7。

Python 3.6的行为原因

  • Python3.6对字典做了重大重构:
    1. 采用了紧凑数组+哈希表的新结构,不仅能保存插入顺序,迭代器也改为基于记录键插入顺序的数组来遍历,而非直接遍历哈希表槽位。
    2. 引入了版本号校验机制:每次修改字典(添加/删除键)都会增加字典的内部版本号,迭代器会在每次迭代时校验版本号。如果发现版本号和迭代开始时不一致,会触发RuntimeError终止迭代——但这里有个特殊情况:当删除的是当前正在迭代的键时,迭代器会允许这次修改,但新添加的键不会被纳入当前的迭代序列。
  • 实际运行中,由于新结构的特性,这种循环不会无限执行,而是在有限几次迭代后终止(你看到的输出到4就是这个原因),本质上是因为迭代器不会去遍历迭代开始后新添加的键,每次删除当前键后,迭代器的后续迭代会逐步耗尽初始的迭代状态,最终停止。

内容的提问来源于stack exchange,提问作者user1717828

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:09:25