python - 为什么有时会保持既定秩序?

标签 python python-3.x for-loop set unordered

当运行此代码时,由于集合是无序的,结果会按预期发生变化:

my_set_1 = {'a','b','c',}
print([i for i in my_set_1])

也就是说,多次运行会给出不同的列表,例如

['a', 'c', 'b']
['b', 'a', 'c']
['a', 'c', 'b']
['c', 'b', 'a']

等等

(注意:如果您没有 PYTHONHASHSEED=random,您可能会得到相同的结果,如评论中所建议的那样。另外,如果您是使用控制台复制它,确保每次运行代码时都重新运行控制台。)


但是,当将上述代码放在 for 循环中时,结果相当令人惊讶:

for i in range(10):
    my_set_1 = {'a','b','c',}
    print([i for i in my_set_1])
# Prints: 
# ['a', 'c', 'b']
# ['a', 'c', 'b']
# ['a', 'c', 'b']
# ....

单次运行 for 循环将打印相同的列表。重新运行 for 循环可以打印不同的列表(例如 ['c', 'b', 'a']),但它仍然会打印 10 次而不会改变。

为什么不改变?

最佳答案

@ReblochonMasque 有一个正确的观点:set 基于哈希表,如果两次运行之间计算的哈希值相同,则两次运行之间的顺序相同。然而,这种行为容易受到 attacks 的攻击。 .

为了防止这些攻击,特殊变量 PYTHONHASHSEED被介绍。当它设置为 random 时,每次运行 Python 都会为相同的项目生成不同的哈希值。这就是您获得不同顺序的原因。

要检查这一点,您可以将 PYTHONHASHSEED 设置为相同的数字来运行您的程序。运行顺序相同。

$ export PYTHONHASHSEED=random
$ python t.py
['a', 'b', 'c']
$ python t.py
['a', 'c', 'b']
$ python t.py
['c', 'b', 'a']
$ export PYTHONHASHSEED=4
$ python t.py
['a', 'b', 'c']
$ python t.py
['a', 'b', 'c']
$ python t.py
['a', 'b', 'c']

如果您查看 object.__hash__() .底部有一条注释(正是关于您的情况):

Note By default, the __hash__() values of str, bytes and datetime objects are "salted" with an unpredictable random value. Although they remain constant within an individual Python process, they are not predictable between repeated invocations of Python.

关于python - 为什么有时会保持既定秩序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32164885/

相关文章:

python - easy_install-3.2.exe 对比 easy_install.exe?

Java foreach 循环中的微妙之处

arrays - 基于 array.count 生成 imageView - Swift

python - 在其他 2d 列表中搜索数组元素并在 python 中计算子列表

python - 如何在程序中添加列表的总和? (Python)

python - 如何比较2个不同的csv文件并输出差异

python - 将 python 字符串转换为 numpy 数组

python - Django:根据查询集中的日期名称创建逗号分隔列表

python - 如何将列表的元素作为变量返回?

javascript - 从两个循环中获取增量数