正如标题所述,为什么下面的代码表现得如此奇怪?
a = {
0: 0
}
b = []
for i in a:
del a[i]
a[i + 1] = 0
b.append(i)
print(b)
在Python3.6中,它打印[0, 1, 2, 3, 4]
,而在Python3.5中,它打印[0, 1, 2, 3, 4, 5, 6, 7]
。为什么?
答案 0 :(得分:7)
在两种情况下,循环都不是无限简单的原因:您在dict上创建了一个迭代器。这只是一个内部知道哈希表大小并跟踪其到达索引的对象。遍历此可迭代对象时,它将仅检查哈希表中的每个插槽以查看是否已填充,如果已填充则产生它,否则它将继续增加索引。
您的字典永远不会增长,它总是具有零个或一个元素,因此不会重新分配哈希表,并且迭代器会继续到哈希表的末尾。
此外:对自己的小整数哈希:
>>> print(*map(hash, range(10)))
0 1 2 3 4 5 6 7 8 9
这意味着,当您插入i+1 == 1
时,它将终止于哈希表的插槽1
中,并且迭代器将在下一个循环中找到它。 2
等也会发生同样的情况。直到哈希码足够大,可以“包装”到哈希表的开头。迭代器索引不会结束,因为它知道哈希表的大小。
Python3.5和python3.6可能具有不同的初始哈希表大小(请记住,在python3.6中,dict
类已重新实现为有序的)。
很显然,所有这些都是实施的详细信息。没有语言保证迭代器的行为是这样,这只是实现的副作用。将来的实现可能会检测到dict
的任何更改并引发错误,而不是继续。