<分区>
正如标题所说,为什么下面的代码表现得如此奇怪?
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]
。为什么?
<分区>
正如标题所说,为什么下面的代码表现得如此奇怪?
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]
。为什么?
最佳答案
在这两种情况下,循环都不是无限的,原因很简单:您在字典上创建了一个迭代器。这只是一个内部知道哈希表大小并跟踪它到达的索引的对象。当遍历这个可迭代对象时,它会简单地检查散列表中的每个槽,看它是否已满,如果已满,则产生它,否则它会继续增加索引。
您的字典的大小永远不会增长,它总是有零个或一个元素,因此不会重新分配哈希表,迭代器会继续到哈希表的末尾。
此外:小整数散列自身:
>>> 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
类被重新实现以进行排序)。
显然,所有都是实现细节。没有语言保证迭代器会像这样运行,这只是实现的副作用。 future 的实现可能会检测到 dict
的任何更改并引发错误而不是继续。
关于python - 为什么下面的代码表现得如此奇怪? Python3.5 与 Python3.6,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55312183/