6

私は持っています:

tuple1 = token1, token2
tuple2 = token2, token1
for tuple in [tuple1, tuple2]:
    if tuple in dict:
        dict[tuple] += 1
    else:
        dict[tuple] = 1

ただし、タプル1とタプル2の両方が同じカウントを取得しています。順序が重要になるように2つのもののグループをハッシュする方法は何ですか?

4

3 に答える 3

23

ハッシュ時に順序が考慮されます。

>>> hash((1,2))
1299869600
>>> hash((2,1))
1499606158

これは、オブジェクト自体に固有のハッシュがあることを前提としています。そうでない場合でも、辞書で使用する場合は問題ありません(オブジェクト自体が__eq__メソッドで定義されているように等しくない場合)。

>>> t1 = 'a',hash('a') 
>>> [hash(x) for x in t1]  #both elements in the tuple have same hash value since `int` hash to themselves in cpython
[-468864544, -468864544]
>>> t2 = hash('a'),'a'
>>> hash(t1)
1486610051
>>> hash(t2)
1486610051
>>> d = {t1:1,t2:2}  #This is OK.  dict's don't fail when there is a hash collision
>>> d
{('a', -468864544): 1, (-468864544, 'a'): 2}
>>> d[t1]+=7
>>> d[t1]
8
>>> d[t1]+=7
>>> d[t1]
15
>>> d[t2]   #didn't touch d[t2] as expected.
2

ハッシュの衝突のため、このdictは、ハッシュの衝突がない別のdictよりも効率が悪い可能性があることに注意してください:)

于 2013-01-17T21:18:41.893 に答える
7

それらが同じカウントを取得する理由は、コードが明示的に両方token1,token2をインクリメントtoken2,token1し、同時にカウントするためです。そうしないと、カウントはロックステップに留まりません。

In [16]: import collections

In [17]: d = collections.defaultdict(int)

In [18]: d[1,2] += 1

In [19]: d[1,2]
Out[19]: 1

In [20]: d[2,1]
Out[20]: 0
于 2013-01-17T21:19:04.867 に答える
0

ループの本体のインスタンスを 1 つ投稿したようです。collections.Counterあなたがやろうとしていることのために使用することを提案するかもしれ ません.

counter = (collections.Counter(myListOfTuples) + 
           collections.Counter([j,i for i,j in myListOfTuples]))
于 2013-01-17T21:25:23.180 に答える