Python - Когда идентифицируются повторяющиеся элементы, какой объект берет набор или морозилка? - PullRequest
2 голосов
/ 25 ноября 2010

У меня есть пользовательский класс MyClass, который имеет реализацию __hash__ и __eq__, которая гарантирует, например,

>>> a = MyClass([100, 99, 98, 97])
>>> b = MyClass([99, 98, 97, 100])
>>> a.__hash__() == b.__hash__()
True
>>> a == b
True

Вопрос: если я сделаю следующее:

>>> x = [a, b]
>>> set(x)

Могу ли я рассчитывать на set, сохраняя a? Является ли набор __init__ итерацией по x по порядку? Или мне нужно беспокоиться о том, что b будет случайным образом?

Спасибо

Mike

Ответы [ 3 ]

3 голосов
/ 25 ноября 2010

В этих случаях, связанных с хэшем, он использует как __hash__, так и __eq__.

Если __hash__ и __eq__ одинаковы, то первый, в который он попадаетитерация берется.Когда он добирается до следующего, он проверяет, есть ли он у него, и решает, что да.

>>> class Same(object):
...     def __init__(self, value):
...         self.value = value
...     def __hash__(self):
...         return 42
...     def __eq__(self, other):
...         return True
...     def __repr__(self):
...         return 'Same(%r)' % self.value
>>> set([Same(2), Same(1)])
set([Same(2)])
>>> set([Same(1), Same(2)])
set([Same(1)])

С dict становится интереснее:

>>> {Same(1): 1, Same(2): 2}
{Same(1): 2}
>>> {Same(1): 2, Same(2): 1}
{Same(1): 1}
>>> {Same(2): 1, Same(2): 2}
{Same(2): 2}
>>> {Same(2): 2, Same(2): 1}
{Same(2): 1}
>>> {Same(2): 2, Same(2): 1}
{Same(2): 1}

Вам следуетв состоянии угадать, что здесь происходит.Он хранит первый элемент, тогда хэш / равенство второго совпадает;однако, у него есть другое значение, поэтому он хранит его.Значение всегда перезаписывается независимо от того, совпадают они или нет:

>>> {Same(1): Same(2), Same(3): Same(4)}
{Same(1): Same(4)}

Надеюсь, это поможет.

1 голос
/ 25 ноября 2010

Я считаю, что set () требует, чтобы оба хэш и eq были переопределены.В этом случае вы могли бы иметь hash (a) == hash (b), но при этом иметь a! = B, предполагая, что вы определили eq таким образом

1 голос
/ 25 ноября 2010

setdict) проверяют не только равенство хешей, но и равенство самих объектов.

...