Issue 26614: False/0 and True/1 collision when used as dict keys? (original) (raw)
Issue26614
Created on 2016-03-23 03:04 by nickeubank, last changed 2022-04-11 14:58 by admin. This issue is now closed.
Messages (4) | ||
---|---|---|
msg262232 - (view) | Author: nickeubank (nickeubank) | Date: 2016-03-23 03:03 |
Found an odd behavior I'd never known about today, not sure if it's a bug or known. Python 3.4.4 (anaconda) True, False, 0, 1 can all be used as dictionary keys. But Apparently True and 1 hash to the same item and False and 0 hash to the same item, so they can easily overwrite (which I spent a while banging my head over today). In other words: In[1]: d = {True: 'a', False: 'b'} d[0] = 'z' d[False] Out[1]: 'z' | ||
msg262234 - (view) | Author: Ethan Furman (ethan.furman) * ![]() |
Date: 2016-03-23 03:11 |
False and True are subtypes of int, so the behaviour you are seeing is known and expected. https://docs.python.org/2/reference/datamodel.html?highlight=bool In the future feel free to ask on Python-List about behaviour -- you'll be sure to get a plethora of answers. | ||
msg262336 - (view) | Author: Mark Dickinson (mark.dickinson) * ![]() |
Date: 2016-03-24 12:34 |
"Apparently True and 1 hash to the same item and False and 0 hash to the same item" Just to clear up a possible misconception here, the key point here is not that they hash to the same integer, but that they're *equal*: >>> True == 1 True >>> False == 0 True In contrast, here are two elements whose hash is equal but which serve as distinct keys: >>> hash(-1) == hash(-2) True >>> len({-1: -1, -2: -2}) 2 IOW, dictionary semantics are defined in terms of equality, not hashing. The hashing part should really be thought of as just a (somewhat exposed) implementation detail. | ||
msg262338 - (view) | Author: STINNER Victor (vstinner) * ![]() |
Date: 2016-03-24 12:47 |
Many values have the same hash value, it's not an issue. The hash is only a best effort function to reduce hash collision, but hash collision is well handled in the dict type (as explained in other messages). >>> hash(1) == hash(1.0) == hash(1.0+0j) == 1 True >>> hash('') == hash(b'') == hash(0) == hash(0.0) == hash(0.0j) == 0 True |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:58:28 | admin | set | github: 70801 |
2016-03-24 12:47:51 | vstinner | set | nosy: + vstinnermessages: + |
2016-03-24 12:34:38 | mark.dickinson | set | nosy: + mark.dickinsonmessages: + |
2016-03-23 03:11:09 | ethan.furman | set | status: open -> closednosy: + ethan.furmanmessages: + resolution: not a bugstage: resolved |
2016-03-23 03:04:00 | nickeubank | create |