2012-06-18 86 views
4

我正在尋找一種更有效的方法來比較python字典的所有元素之間的比較。python字典的所有元素的高效比較

下面是我在做什麼僞代碼:

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

如果字典的長度爲N,這是N^2 - N.是否有在第二循環中沒有重複元素的任何方式?對於名單,這將是:

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

無論如何做這個爲字典的情況?

回答

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)。 [當然,如果你想要一個特定的順序,你可以遍歷​​或某些變體,或者如果這個問題比較(k0,k1)和(k1,k0),如果重要的話。]

[順便說一句:不要打電話給你的列表列表或你的類型的字典dict--該則會覆蓋的建宏,而且他們觸手可及,]

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 
+0

@senderle我編輯了我的答案w舉一個例子。 – srgerg

+0

啊,我明白了,很好。 – senderle

+0

@srgerg:確實不錯,但你實際上並不需要OrderedDict,只是'對於排序後的(d)' – georg

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 

該解決方案是相當有效:all是鐳石光電 - 停止在第一False和發電機表達鐳石光電太:) :)

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