gpt4 book ai didi

python - 为什么字典排序是不确定的?

转载 作者:行者123 更新时间:2023-11-28 19:15:39 25 4
gpt4 key购买 nike

我最近从 Python 2.7 切换到 Python 3.3,看起来虽然在 Python 2 中字典键的顺序是任意但一致的,但在 Python 3 中,字典键的顺序是通过例如vars()似乎是不确定的。

如果我运行:

class Test(object): pass
parameters = vars(Test)
print(list(parameters.keys()))

在 Python 2.7 和 Python 3.3 中,然后:

  • Python 2.7 一直给我

    ['__dict__', '__module__', '__weakref__', '__doc__']
  • 使用 Python 3.3,我可以获得任何随机顺序——例如:

    ['__weakref__', '__module__', '__qualname__', '__doc__', '__dict__']
    ['__doc__', '__dict__', '__qualname__', '__module__', '__weakref__']
    ['__dict__', '__module__', '__qualname__', '__weakref__', '__doc__']
    ['__weakref__', '__doc__', '__qualname__', '__dict__', '__module__']

这种不确定性从何而来?为什么是这样的

list({str(i): i for i in range(10)}.keys())

…运行之间保持一致,始终给予

['3', '2', '1', '0', '7', '6', '5', '4', '9', '8']

……?

最佳答案


更新:在 Python 3.6 中,dict 有一个 new implementation保留插入顺序。从 Python 3.7 开始,这种保序行为是 guaranteed :

the insertion-order preservation nature of dict objects has been declared to be an official part of the Python language spec.


这是 security fix 的结果从 2012 年开始,即 enabled by default在 Python 3.3 中(向下滚动到“安全改进”)。

来自公告:

Hash randomization causes the iteration order of dicts and sets to be unpredictable and differ across Python runs. Python has never guaranteed iteration order of keys in a dict or set, and applications are advised to never rely on it. Historically, dict iteration order has not changed very often across releases and has always remained consistent between successive executions of Python. Thus, some existing applications may be relying on dict or set ordering. Because of this and the fact that many Python applications which don't accept untrusted input are not vulnerable to this attack, in all stable Python releases mentioned here, HASH RANDOMIZATION IS DISABLED BY DEFAULT.

如上所述,最后一位大写的位在 Python 3.3 中不再为真。

另请参阅: object.__hash__() documentation (“注释”边栏)。

如果绝对必要,您可以通过设置 PYTHONHASHSEED 来禁用受此行为影响的 Python 版本中的哈希随机化。环境变量为 0


你的反例:

list({str(i): i for i in range(10)}.keys())

... not 实际上在 Python 3.3 中总是给出相同的结果,尽管不同排序的数量有限 due to哈希冲突的处理方式:

$ for x in {0..999}
> do
> python3.3 -c "print(list({str(i): i for i in range(10)}.keys()))"
> done | sort | uniq -c
61 ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
73 ['1', '0', '3', '2', '5', '4', '7', '6', '9', '8']
62 ['2', '3', '0', '1', '6', '7', '4', '5', '8', '9']
59 ['3', '2', '1', '0', '7', '6', '5', '4', '9', '8']
58 ['4', '5', '6', '7', '0', '1', '2', '3', '8', '9']
55 ['5', '4', '7', '6', '1', '0', '3', '2', '9', '8']
62 ['6', '7', '4', '5', '2', '3', '0', '1', '8', '9']
63 ['7', '6', '5', '4', '3', '2', '1', '0', '9', '8']
60 ['8', '9', '0', '1', '2', '3', '4', '5', '6', '7']
66 ['8', '9', '2', '3', '0', '1', '6', '7', '4', '5']
65 ['8', '9', '4', '5', '6', '7', '0', '1', '2', '3']
53 ['8', '9', '6', '7', '4', '5', '2', '3', '0', '1']
62 ['9', '8', '1', '0', '3', '2', '5', '4', '7', '6']
52 ['9', '8', '3', '2', '1', '0', '7', '6', '5', '4']
73 ['9', '8', '5', '4', '7', '6', '1', '0', '3', '2']
76 ['9', '8', '7', '6', '5', '4', '3', '2', '1', '0']

如本答案开头所述,Python 3.6 不再是这种情况:

$ for x in {0..999}
> do
> python3.6 -c "print(list({str(i): i for i in range(10)}.keys()))"
> done | sort | uniq -c
1000 ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

关于python - 为什么字典排序是不确定的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33810024/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com