Могу ли я безопасно использовать хеши кортежей, содержащих 64-битные целые (длинные), в качестве уникальных ключей в словаре Python? - PullRequest
0 голосов
/ 05 октября 2010

Я должен хранить объекты, которые имеют два атрибута (ida и idb) внутри dict.Оба атрибута являются 64-битными натуральными числами, и я могу хранить только один объект для уникального расположения (комбинация, в которой важен порядок) ida и idb.Например:

obj1 = SomeClass(ida=5223372036854775807, idb=2)
obj2 = SomeClass(ida=2, idb=5223372036854775807)
obj3 = SomeClass(ida=5223372036854775807, idb=2)

Поскольку сами объекты являются изменяемыми, в качестве ключей я использую хэши кортежей '(ida, idb,)'.В следующем примере рассмотрим следующее:

d = {}
# storing obj1
k1 = hash((obj1.ida, obj1.idb,))
d[k1] = obj1
# storing obj2
k2 = hash((obj2.ida, obj2.idb,))
d[k2] = obj2
# storing obj3
k3 = hash((obj3.ida, obj3.idb,)) # note that k3 hash should be the same as k1
d[k3] = obj3
#at this point 'd' should contain only 'obj2' and 'obj3' since 'k1' == 'k3'

Я протестировал приведенный выше пример на моей 64-битной машине, и он работал как ожидалось.

У меня есть следующие вопросы:

  • Возможно ли для двух кортежей больших целых чисел вычислять один и тот же хеш, если они имеют различия в элементах или в порядке следования?
  • А как насчет 32-битных платформ?
  • Если нет,существует ли независимый от платформы способ гарантировать, что приведенный выше пример будет работать независимо от значений ida и idb?

Ответы [ 3 ]

2 голосов
/ 05 октября 2010
In [33]: hash?

Возвращает значение хеш-функции для объекта.Два объекта с одинаковым значением имеют одинаковое значение хеш-функции. Обратное не обязательно верно, но вероятно .

Почему бы просто не использовать кортеж (ida, idb) в качестве ключа?

import pprint
class SomeClass(object):
    def __init__(self,ida,idb):
        self.ida=ida
        self.idb=idb
obj1 = SomeClass(ida=5223372036854775807, idb=2)
obj2 = SomeClass(ida=2, idb=5223372036854775807)
obj3 = SomeClass(ida=5223372036854775807, idb=2)

d={}
for obj in (obj1,obj2,obj3):
    d[obj.ida,obj.idb]=obj

pprint.pprint(d)
# {(2, 5223372036854775807L): <__main__.SomeClass object at 0xb78839ec>,
   (5223372036854775807L, 2): <__main__.SomeClass object at 0xb7883a0c>}
1 голос
/ 05 октября 2010

Как сказал Игнасио, вы можете столкнуться с хешем. Почему бы тебе просто не использовать сам кортеж? Кортежи неизменны, и, похоже, ваши ida и idb являются (неизменяемыми) целыми числами.

0 голосов
/ 05 октября 2010

Есть только 2 **возможные хеши, так что вам придется запустить 128-битную версию Python, чтобы даже сохранить все (2 ** 64) ** 2 возможных хеша.И да, может все же быть возможным иметь столкновения.Используйте set, если вам нужно хранить уникальные объекты;просто определите __hash__() и __eq__() в здравом смысле.

...