当运行此代码时,由于集合是无序的,结果会按预期发生变化:
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 ofstr
,bytes
anddatetime
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/