heapq.nlargest产生不一致的结果

时间:2016-05-19 22:19:57

标签: python heap

如果多次执行,以下代码会产生不一致的结果。我使用Python-3.5.1在Debian 8.4(jessie)上运行它。

from heapq import nlargest
from operator import itemgetter

dd = dict([('41', 768.0), ('2', 15275.0), ('9', 1728.0), ('90', 1728.0),
           ('97', 1200.0), ('68', 2904.0), ('98', 4380.0), ('16', 768.0),
           ('37', 768.0), ('17', 1587.0), ('25', 4495.4)])

print(nlargest(5, dd.items(), key=itemgetter(1)))

多次执行后的输出:

[('2', 15275.0), ('25', 4495.4), ('98', 4380.0), ('68', 2904.0), ('90', 1728.0)]
[('2', 15275.0), ('25', 4495.4), ('98', 4380.0), ('68', 2904.0), ('9', 1728.0)]
[('2', 15275.0), ('25', 4495.4), ('98', 4380.0), ('68', 2904.0), ('90', 1728.0)]
[('2', 15275.0), ('25', 4495.4), ('98', 4380.0), ('68', 2904.0), ('90', 1728.0)]

看起来很随机,有人可以解释为什么会这样吗?

如果用dd.items()替换sorted(dd.items()),则输出变为确定性。即。

[('2', 15275.0), ('25', 4495.4), ('98', 4380.0), ('68', 2904.0), ('9', 1728.0)]

我还尝试使用python-2.7在OSX和CentOS6.7上面编写代码,它总是返回

[('2', 15275.0), ('25', 4495.4), ('98', 4380.0), ('68', 2904.0), ('9', 1728.0)]

这可能是Python3 heapq实施中的错误吗?

1 个答案:

答案 0 :(得分:1)

你要求的是5个最大的项目,并且排在第5位。 Python如何打破平局是任意的,所涉及的任何非确定行为都不是错误。

它不确定性的原因是因为dict迭代顺序是任意的,并且自Python 3.3以来,默认情况下已启用字符串和某些其他类型的散列随机化。因此,heapq.nlargest接收dict项的顺序有一个随机组件,它断开关系的方式取决于它看到项的顺序。