用于收集忽视排序的项目的哈希函数

Grz*_*orz 4 python hash cryptography hashcode

我正在使用该hash()函数来获取包含两个整数和两个字符串的对象的哈希值.而且,我有一个字典,我存储这些对象; 过程是我检查对象是否存在哈希值,如果是,我更新,如果不是我插入新的.

问题在于,在创建对象时,我不知道对象变量的顺序,我想将对象视为相同,无论这些变量的顺序如何.

是否有一个函数的替代函数hash()不考虑变量的顺序?

#Consequently what I want is:
hash((int1,str1,int2,str2)) == hash((int2,str2,int1,str1)) 
Run Code Online (Sandbox Code Playgroud)

Mos*_*oye 10

您可以使用frozenset而不是元组:

>>> hash(frozenset([1, 2, 'a', 'b']))
1190978740469805404
>>>
>>> hash(frozenset([1, 'a', 2, 'b']))
1190978740469805404
>>>
>>> hash(frozenset(['a', 2, 'b', 1]))
1190978740469805404
Run Code Online (Sandbox Code Playgroud)

但是,从迭代中删除重复项会产生一个微妙的问题:

>>> hash(frozenset([1,2,1])) == hash(frozenset([1,2,2]))
True
Run Code Online (Sandbox Code Playgroud)

您可以通过使用迭代创建一个计数器collections.Counter并调用frozenset计数器的项来解决这个问题,从而保留原始iterable中每个项的计数:

>>> from collections import Counter
>>>
>>> hash(frozenset(Counter([1,2,1]).items())) 
-307001354391131208
>>> hash(frozenset(Counter([1,1,2]).items()))
-307001354391131208
>>> 
>>> hash(frozenset(Counter([1,2,1]).items())) == hash(frozenset(Counter([1,2,2]).items()))
False
Run Code Online (Sandbox Code Playgroud)