问题
For example, when I execute frozen = frozenset(('kay', 'snow queen'))
, then tuple(frozen)
, I get ('kay', 'snow queen')
. (When / how) is it possible, if ever, for iter(frozen)
to produce the items in a different order? (When / how) will tuple(frozen)
return ('snow queen', 'kay')
?
I am using Python 3 almost all of the time, but I would also be curious about Python 2.
回答1:
By default, the hash values of str
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. Changing hash values affects the iteration order of sets.
So, when hash randomization is on, you will get items in a different order:
$ for i in {1..10}; do python3 -c "frozen = frozenset(('kay', 'snow queen')); print(list(frozen))"; done
['snow queen', 'kay']
['snow queen', 'kay']
['snow queen', 'kay']
['snow queen', 'kay']
['kay', 'snow queen']
['kay', 'snow queen']
['snow queen', 'kay']
['kay', 'snow queen']
['snow queen', 'kay']
['snow queen', 'kay']
If you disable it, you will get a repeatable but arbitrary order:
$ export PYTHONHASHSEED=0
$ for i in {1..10}; do python3 -c "frozen = frozenset(('kay', 'snow queen')); print(list(frozen))"; done
['kay', 'snow queen']
['kay', 'snow queen']
['kay', 'snow queen']
['kay', 'snow queen']
['kay', 'snow queen']
['kay', 'snow queen']
['kay', 'snow queen']
['kay', 'snow queen']
['kay', 'snow queen']
['kay', 'snow queen']
Since Python 3.3, hash randomization is enabled by default to workaround a security vulnerability.
See also: the -R switch to the interpreter.
来源:https://stackoverflow.com/questions/52768966/is-iterating-over-the-same-frozenset-guaranteed-always-to-produce-the-items-in-t