简体   繁体   中英

Python - hash() and dict

If we have 2 separate dict , both with the same keys and values , when we print them it will come in different orders, as expected.
So, let's say I want to to use hash() on those dict :

hash(frozenset(dict1.items()))
hash(frozenset(dict2.items()))

I'm doing this to make a new dict with the hash() value created as the new keys .
Even showing up different when printing dict , the value createad by hash() will always be equal? If no, how to make it always the same so I can make comparisons successfully?

If the keys and values hash the same, frozenset is designed to be a stable and unique representation of the underlying values. The docs explicitly state :

Two sets are equal if and only if every element of each set is contained in the other (each is a subset of the other).

And the rules for hashable types require that :

Hashable objects which compare equal must have the same hash value.

So by definition frozenset s with equal, hashable elements are equal and hash to the same value. This can only be violated if a user-defined class which does not obey the rules for hashing and equality is contained in the resulting frozenset (but then you've got bigger problems).

Note that this does not mean they'll iterate in the same order or produce the same repr ; thanks to chaining on hash collisions, two frozenset s constructed from the same elements in a different order need not iterate in the same order. But they're still equal to one another, and hash the same (precise outputs and ordering is implementation dependent, could easily vary between different versions of Python; this just happens to work on my Py 3.5 install to create the desired "different iteration order" behavior):

>>> frozenset([1,9])
frozenset({1, 9})
>>> frozenset([9,1])
frozenset({9, 1}) # <-- Different order; consequence of 8 buckets colliding for 1 and 9
>>> hash(frozenset([1,9]))
-7625378979602737914
>>> hash(frozenset([9,1]))
-7625378979602737914 # <-- Still the same hash though
>>> frozenset([1,9]) == frozenset([9,1])
True # <-- And still equal

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM