- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
输出
d = {1: 1}
for k in d.keys():
d['{}'.format(k)] = d.pop(k)
print(d)
是 {'1': 1}
。的输出
d = {1: 1}
for k in d.keys():
d['i{}'.format(k)] = d.pop(k)
print(d)
是 {'iiiii1': 1}
。这是一个错误吗?我正在运行 Python 3.6.1::Anaconda 4.4.0 (x86_64)
。
最佳答案
不,这不是错误。这实际上是explicitly documented :
Keys and values are iterated over in an arbitrary order which is non-random, varies across Python implementations, and depends on the dictionary’s history of insertions and deletions. If keys, values and items views are iterated over with no intervening modifications to the dictionary, the order of items will directly correspond.
[...]
Iterating views while adding or deleting entries in the dictionary may raise a
RuntimeError
or fail to iterate over all entries.
大胆强调我的。
您正在遍历键,同时在字典中添加和删除条目。这适用于几次迭代,然后您遇到了无法迭代所有条目的情况,迭代停止了。
发生的情况是您在添加 6 次时触发重新调整大小,这会导致迭代在该点失败; “下一个”键现在位于“较早”的位置。 两种 测试都会发生这种情况,您只是没有意识到它在两种情况下都迭代了 5 次:
>>> d = {1: 1}
>>> for i, k in enumerate(d):
... print(i)
... d['{}'.format(k)] = d.pop(k)
...
0
1
2
3
4
>>> d = {1: 1}
>>> for i, k in enumerate(d):
... print(i)
... d['i{}'.format(k)] = d.pop(k)
...
0
1
2
3
4
它运行了 5 次,因为当前的 dict
实现以 hash table of size 8 开头,并触发调整大小 when the table is 2/3s full (您的初始字典有 1 个条目,5 次插入使其成为 > (8 * 2/3 == 5.333333)
。表格中充满了 DKIX_DUMMY
entities ,当您删除一个键时输入(需要正确处理哈希冲突)。
请注意,这完全取决于实现。在 Python 3.5 及之前的版本中,两个代码片段都只迭代一次(即使您使用 for k in d:
来避免为键创建列表对象);迭代在 3.6 中继续,因为实现发生了变化,迭代现在遵循插入顺序。 future 的 Python 版本可以再次自由更改实现。
关于python - 在遍历字典的同时修改字典。 Python 字典中的错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44763802/
我是一名优秀的程序员,十分优秀!