为什么Python 3.3+ dict排序不仅是未定义的,而且是变量的?

时间:2015-12-10 18:57:26

标签: python django

我出于好奇而问这个问题(特别是深入了解python如何在幕后工作)。

我完全清楚python dict对象是无序的 - 你可以放入一堆项目,并打印出dict的一些表示,以及表示中项目的顺序将不会与输入项目的顺序相对应。

然而,令我感到好奇的是,为什么订单会从一次执行代码变为另一次执行?

我有一个非常简单的python脚本,它将dict打印到控制台。字典看起来像这样(内容非常无关紧要):

{
    'hello': 'hi',
    'goodbye': 'bye',
    'hahaha': 'lol',
}

将其打印到控制台会导致项目不仅以随机顺序打印,而且每次运行程序时都以不同的顺序打印 。这是我的问题:为什么会这样?

注意:python代码在django项目中(但在这种情况下,我没有使用任何django功能 - 只要提及它,以防它以某种方式相关)。

1 个答案:

答案 0 :(得分:7)

这里有一个关于此的说明:https://docs.python.org/3/reference/datamodel.html#object.__hash__

以下是注释:

  
    

注意:默认情况下,str,bytes和datetime对象的__hash__()值使用不可预测的随机值“加盐”。尽管它们在单个Python进程中保持不变,但在重复调用Python之间无法预测它们。     这旨在提供针对由精心选择的输入引起的拒绝服务的保护,该输入利用dict插入的最坏情况性能,O(n ^ 2)复杂度。有关详细信息,请参阅http://www.ocert.org/advisories/ocert-2011-003.html。     更改哈希值会影响dicts,集和其他映射的迭代顺序。 Python从未对这种排序做出保证(通常在32位和64位版本之间有所不同)。

         

另见PYTHONHASHSEED

  
     

在版本3.3中更改:默认情况下启用哈希随机化。