gpt4 book ai didi

python - 为什么 Python list() 并不总是具有相同的顺序?

转载 作者:行者123 更新时间:2023-11-30 22:27:10 27 4
gpt4 key购买 nike

我正在使用 Python 3.5 及其文档,位于 https://docs.python.org/3.5/library/stdtypes.html#sequence-types-list-tuple-range说:

list([iterable])

(...)

The constructor builds a list whose items are the same and in the same order as iterable’s items. 

好的,对于以下脚本:

#!/usr/bin/python3

import random

def rand6():
return random.randrange(63)


random.seed(0)
check_dict = {}

check_dict[rand6()] = 1
check_dict[rand6()] = 1
check_dict[rand6()] = 1

print(list(check_dict))

我总是得到

[24, 48, 54]

但是,如果我将函数更改为:

def rand6():
return bytes([random.randrange(63)])

那么返回的顺序并不总是相同的:

>./foobar.py
[b'\x18', b'6', b'0']
>./foobar.py
[b'6', b'0', b'\x18']

为什么?

最佳答案

Python 字典是作为哈希表实现的。在大多数 Python 版本中(稍后详细介绍),迭代字典时获取键的顺序是表中值的任意顺序,这与它们的添加顺序关系不大(当发生哈希冲突时,插入的顺序可能会有点影响)。该顺序取决于实现。 Python 语言不提供任何关于顺序的保证,只是如果中间没有添加或删除键,则在字典的多次迭代中它将保持不变。

对于带有整数键的字典,哈希表不会做任何花哨的事情。整数对自身进行哈希处理(-1 除外),因此将相同的数字放入字典中,您将在哈希表中获得一致的顺序。

但是,对于具有 bytes 键的字典,由于哈希随机化,您会看到不同的行为。为了防止一种字典冲突攻击(其中用 Python 实现的 Web 应用程序可以通过向其发送具有数千个 key 的数据来进行攻击,这些 key 哈希为相同的值,从而导致大量冲突并且非常糟糕(O(N**2 ))性能),Python 每次启动时都会选择一个随机种子,并使用它来随机化 Unicode 和字节字符串以及 datetime 类型的哈希函数。

您可以通过将环境变量 PYTHONHASHSEED 设置为 0 来禁用哈希随机化(或者您可以通过将其设置为最大 的任何正整数来选择自己的种子) >2**32-1)。

值得注意的是,这种行为在 Python 3.6 中发生了变化。哈希随机化仍然发生,但字典的迭代顺序不再基于键的哈希值。虽然官方语言政策仍然是顺序是任意的,但 CPython 中 dict 的实现现在保留了其值添加的顺序。在使用常规 dict 时,您不应该依赖此行为,因为开发人员有可能(尽管目前看来不太可能)认为这是一个错误并再次更改实现。如果您想保证迭代按特定顺序发生,请使用collections.OrderedDict类而不是普通的dict

关于python - 为什么 Python list() 并不总是具有相同的顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47008930/

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