2013-01-15 58 views
0

我想比較一個Python字典和它自己。例如:在Python中比較字典本身

for key1 in d: 
    for key2 in d: 
     if key1 == key2: 
      continue 
     compare(d[key1],d[key2]) 

上面將除我比較KEY1與鍵2,然後後來反向(KEY2與KEY1)工作。第二個for循環的範圍應該在key1之後開始,以避免重複比較。如何做到這一點?

+1

難道我們要求使用的情況下,請 - 它只是似乎有點古怪做到這一點... –

+0

@ mgilson我想我誤解了代碼。 –

+3

@AshwiniChaudhary - 無後顧之憂。所以,其他4人顯然:) – mgilson

回答

3

我認爲itertools.combinations會有幫助這裏

>>> import itertools 
>>> d = dict.fromkeys(range(5),0) 
>>> list(itertools.combinations(d,2)) 
[(0, 1), (0, 2), (0, 3), (0, 4), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)] 

所以,對於你的情況,你會想:

for key1,key2 in itertools.combinations(d,2): 
    compare(d[key1],d[key2]) 

這是一個愚蠢的例子我構建對人的名單與棕色的眼睛(或頭髮我想......):

>>> d = dict.fromkeys(["Jon","Jane","Bob","Jim","Janice"],"blue") 
>>> d["Jim"] = "Brown" 
>>> d["Jane"] = "Brown" 
>>> d["Bob"] = "Brown" 
>>> [ (x,y) for (x,y) in itertools.combinations(d,2) if d[x]=="Brown" and d[y]=="Brown" ] 
[('Jane', 'Bob'), ('Jane', 'Jim'), ('Bob', 'Jim')] 
+0

這讓我很擔心。如果字典很大,該怎麼辦? – jensph

+0

@jensph - 這有什麼問題?我的循環使用'itertools'來完成,它不會一次全部存儲在內存中。 (所有存儲在我的第一個例子中的唯一原因是我從迭代器中明確構造了一個'list')。當然,'itertools'需要做一些緩存,但肯定不會超過'N = len(d)'元素。 – mgilson

+0

我認爲它需要len(d)* len(d)。無論如何,這個工作很好! – jensph

1

其實你不需要鑰匙推遲字典。正如@mgilson建議,您可以使用itertools.combinations比較字典的值直接

>>> from itertools import combinations 
>>> d = {random.randint(1,100):i for i in range(10)} 
>>> list(combinations(d.values(), 2)) 
[(7, 4), (7, 2), (7, 3), (7, 1), (7, 0), (7, 8), (7, 9), (7, 5), (7, 6), (4, 2), (4, 3), (4, 1), (4, 0), (4, 8), (4, 9), (4, 5), (4, 6), (2, 3), (2, 1), (2, 0), (2, 8), (2, 9), (2, 5), (2, 6), (3, 1), (3, 0), (3, 8), (3, 9), (3, 5), (3, 6), (1, 0), (1, 8), (1, 9), (1, 5), (1, 6), (0, 8), (0, 9), (0, 5), (0, 6), (8, 9), (8, 5), (8, 6), (9, 5), (9, 6), (5, 6)] 
>>> 
+0

這是真的 - 只要鑰匙並不重要。從鍵 - >值比從另一個方向開始更容易:)。 – mgilson

0

如果你想堅持的嵌套式for循環,然後下面的伎倆:

d = dict(a=1,b=2,c=3,d=4) 
k = d.keys() 
l = len(k) 

for i in range(l): 
    for j in range(i+1,l): 
     print d[k[i]] == d[k[j]] 
+0

謝謝。這符合我的想法。 – jensph

1

要使用itertools.combinations顯然是最好的答案。但即使是這個問題的原代碼需要只是一個很小的修改做些什麼來預計:

for key1 in d: 
    for key2 in d: 
     if key1 < key2: 
      compare(d[key1],d[key2])