Reputation: 47
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?
Upvotes: 1
Views: 4152
Reputation: 155323
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
Upvotes: 4