4

Python dict のすべての要素を比較するより効率的な方法を探しています。

これが私がやっていることの疑似コードです:

for key1 in dict:
    for key2 in dict:
        if not key1 == key2:
            compare(key1,key2)

dict の長さが N の場合、これは N^2 - N です。2 番目のループで要素を繰り返さない方法はありますか? リストの場合、これは次のようになります。

N = len(list)
for i in range(1:(N-1)):
    for j in range((i+1):N):
        compare(list[i], list[j])

とにかく口述の場合にこれを行うには?

4

3 に答える 3

9

多分何かのような

>>> import itertools
>>> 
>>> d = {1:2, 2:3, 3:4}
>>> 
>>> for k0, k1 in itertools.combinations(d,2):
...     print 'compare', k0, k1
... 
compare 1 2
compare 1 3
compare 2 3

(1,2) または (2,1) のどちらを取得するかを気にしない場合。[もちろんsorted(d)、特定の順序が必要な場合は、またはいくつかのバリアントを反復するか、それが重要な場合は (k0, k1) と (k1, k0) の両方を比較できます。]

[ところで: あなたのリストを list や dicts dict と呼ばないでください -- それはビルトインを破壊します。

于 2012-06-18T02:58:10.297 に答える
3

OrderedDictを使用して、既にリスト用に取得したものと同様のコードを記述できます。

次に例を示します。

from collections import OrderedDict

def compare(a, b):
    print "compare", a, b

d = OrderedDict([('banana', 3), ('apple', 4), ('pear', 1), ('orange', 2)])

for key1 in d:
    for key2 in reversed(d):
        if key1 == key2:
            break
        compare(key1, key2)

これを実行すると、次のように出力されます。

compare banana orange
compare banana pear
compare banana apple
compare apple orange
compare apple pear
compare pear orange
于 2012-06-18T02:56:22.443 に答える
0
>>> equal = lambda d1, d2: all(d1.get(k) == d2.get(k) for k in set(d1.keys() + d2.keys()))
>>> print equal({'a':1, 'b':2}, {'b':2, 'a':1})
True
>>> print equal({'a':1, 'b':2}, {'b':2, 'a':2})
False

この解決策は非常に効果的です: allis lasy - 最初Falseで停止し、ジェネレータ式も lasy です :)

def deep_equal(d1, d2):
    ''' Deep comparison '''
    if type(d1) != type(d2):
       return False
    if isinstance(d1, dict):
       return all(ddeep_equal(d1.get(k), d2.get(k))
           for k in set(d1.keys() + d2.keys()))
    return d1 == d2
于 2012-06-18T03:39:55.563 に答える