при создании набора:Почему python устанавливает только False и Zero?
>>> falsey_set = {0, '', False, None} # set([False, '', None])
>>> falsey_set = {False, '', 0, None} # set([0,'', None])
>>> # adding an item to the set doesn't change anything either
>>> falsey_set.add(False) # set([0,'',None])
или словарь, который имитирует поведение несколько:
>>> falsey_dict = {0:"zero", False:"false"} # {0:'false'} # that's not a typo
>>> falsey_dict = {False:'false', 0:'zero'} # {False: 'zero'} # again, not a typo
>>> falsey_set.add(()) # set([0,'', None,()])
>>> falsey_set.add({})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
>>> falsey_dict[()] = 'list' # {False:'zero',():'list'}
>>> falsey_dict({}) = 'dict'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
0
и False
всегда вынимайте друг друга из набора. В словарях они совершенно неверны. Есть ли причина для этого? Хотя я понимаю, что булевы производятся из целых чисел в Python. Что такое питоновское рассуждение для того, чтобы действовать таким образом в контексте множеств в определенном смысле (я не слишком люблю словари)? Так как в то время как полезно в truthy сравнения, как:
>>> False == 0 # True
Существует очевидное значение в дифференциации:
>>> False is 0 # False
Я смотрел по documentation и не могу найти ссылку на поведение
Update
@de lnan Я думаю, вы попали в гвоздь на голове с детерминизмом хэша, о котором вы упоминали в комментариях. Как отмечает @mgilson какFalse
и 0
использовать ту же функцию хэширования, однако так делать object
и многие из его подклассов (т.е .: super
), которые имеют одинаковые хэш-функции. Кажется, что ключ находится во фразе Hashable objects which compare equal must have the same hash value
от documentation. Поскольку False == 0 и оба они хешируемые, их выходы должны быть определены Python равными. Наконец, в определении hashable указано, как наборы используют хешируемость в множестве членства со следующим: Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally.
Хотя я до сих пор не понимаю, почему они оба используют одну и ту же функцию хеширования - я могу согласиться с этим.
Если мы все согласны, тогда кто-то предложит отполированный ответ, и я его приму. Если может быть какое-то улучшение, или если я не в базе, пожалуйста, сообщите ниже.
Зачем нужна идентификация? Две равные строки могут иметь разные тождества, представьте себе боль, если они считаются различными по наборам и диктофонам. Также обратите внимание, что по определению hashability, 'hash (x) == hash (y)' ** должен ** выполняться, когда 'x == y'. – delnan
Связанный вопрос: http://stackoverflow.com/questions/2764017/is-false-0-and-true-1-in-python-an-implementation-detail-or-is-it-guarante. –
Вы не должны слишком зависеть от хэширующей части этого; это в основном не имеет значения.Простой ответ заключается в том, что членство в dict и set (и list, come to that) основано на * равенстве * (если вы не хотите nitpick, и в этом случае лучшее описание - это идентификация-то-равенство), а так как 'False == 0', они считаются одинаковыми при использовании в качестве заданных элементов или клавиш словаря. Тот факт, что dicts и sets использует хэш-таблицу (и, следовательно, ключи и элементы должны быть хешируемыми, а равенство должно подразумевать равенство хэшей) является вторичным. –