2011-12-26 13 views
5

Pythonのfrozensetオブジェクトの入れ子を、Pythonのセッションとプラットフォームで同じユニークな整数に変換するにはどうすればよいですか?Python Frozen Setsの永続ハッシュ

私は

32ビット

Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) 
[GCC 4.4.3] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> a=frozenset([frozenset([1,2,3]),frozenset(['a','b','c'])]); 
>>> hash(a) 
1555175235 

64ビット

Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) 
[GCC 4.4.3] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> a=frozenset([frozenset([1,2,3]),frozenset(['a','b','c'])]); 
>>> hash(a) 
-6076998737938213053 
あなたがユニークにPythonのfrozensetのオブジェクトのネストを変換する方法を

答えて

7

異なるプラットフォーム上)(ハッシュとは異なる値を取得しますPythonセッションとプラットフォームで同じ整数だったのですか?

AFAIKハッシュは一意であるとは限りません。実際には、辞書のようなルックアップテーブルに使用されているハッシュの衝突はかなり一般的です。

と言われています。プラットフォーム全体で一貫性のある一意の「ハッシュ」が必要な場合は、標準ライブラリhashlibを使用しようとします。私は別のプラットフォームでそれを試す可能性はありませんが、そこに実装されているアルゴリズムのほとんど(例えばMD5のもの)はプラットフォームに依存しないと考えています。

私はソートされたバージョンのソートされたセットを使ってハッシュアルゴリズムを供給します。ハッシングに使用する文字列が常に同じであることを確認します。


EDIT:は、基本的な例を追加するために考えた:

>>> import cPickle as pkl 
>>> import hashlib as hl 
>>> s = frozenset([1,2,3]) 
>>> p = pkl.dumps(sorted(s)) #make sure you use the same pickle protocol on all platform! 
'(lp1\nI1\naI2\naI3\na.' 
>>> h = hl.md5(p) 
<md5 HASH object @ 0xb76fb110> 
>>> h.digest() 
"\x89\xaeG\x1d'\x83\xa5\xbd\xac\xa7\x1c\xd9\x1d/2t" #this should be consistent 
+0

価値のあることは、私はpickled frozensetのmd5合計が32ビットと64ビットプラットフォームで同じであることを確認しました。 – jcollado

+0

@jcollado - ありがとう! :) – mac

+1

すべてのプラットフォームで同一のものにピクルすることが保証されている順序のないタイプの酸洗いですか?私はそれができると信じることには消極的です。私はおそらくセットから要素をリストに引き出し、酸漬けにする前にソートします。 – dstromberg

0

また、独自のハッシュ関数を作成することができます。

def hash(fs): 
    res = 1 
    for v in fs: 
     res = (res*31 + v) % 2**30 
    return res 

は、これは必ずしも一意ではありませんが、それはセットハッシュのビルドと同じくらい優れており、プラットフォーム間で結果を完全に制御できます。