4 ms·
Yup. If hash(x) == hash(y), then some_dict[x] and some_dict[y] will return the same value. The int/float is just a convenient red herring on that one, since it'
by ubernostrum 11y ago
Yup. If hash(x) == hash(y), then some_dict[x] and some_dict[y] will return the same value. The int/float is just a convenient red herring on that one, since it's an easy way to get two different-looking keys which hash the same, combined with the double red herring of the initial "can't index" example being a list (which does require integer values for indexing).
- jepler 11y agonope. Here I use the trick that for most ints, hash(i) == i to quickly find two values with the same hash and put them in a dict. >>> k1 = "foo" >>> k2 = hash(k1) >>> hash(k1) == hash(k2) True >>> d = {k1: "v1", k2: "v2"} >>> d[k1] 'v1' >>> d[k2] 'v2' Now that I've been pedantic, I hope I get this right: in Python, it is equality (==) that defines same-ness for dicts and sets. But if x == y, then you have to ensure that hash(x) == hash(y). Python uses this characteristic to make the initial check for dict and set membership integer comparisons on the hash, but when two items have the same hash, Python goes on to distinguish them on the basis of equality.
- rspeer 11y agoOh, while we're talking about things with predictable hashes, here's a Python WTF that I enjoy: class A: def __hash__(self): return -1 print(hash(A())) Prints -2. For the same reason, if you ever need an easy hash collision, use the hashes of -1 and -2.
- rspeer 11y agoI'll explain the reason, BTW: a hash value of -1 isn't valid in CPython because that integer is reserved as a flag value. So any hash method that returns -1 quietly gets its value changed to -2.
- shpx 11y ago> If hash(x) == hash(y), then some_dict[x] and some_dict[y] will return the same value This was my first thought too, so I checked but >>> hash(0) 0 >>> hash(0.0) 0 >>> hash('') 0 >>> {0: 4}[''] KeyError: '' Which makes sense, because there is checking for hash collisions, and when they are resolved 0 == 0.0 while 0 != ''
- SanFranManDan 11y agoIts more like (although Im not sure the exact implementation). def make_key(obj): return (obj.__class__.__module__, obj.__class__.__name__, hash(obj)) make_key(x) == make_key(y)