2013-12-10 122 views
4

我想知道您是否可以幫助我。如何:比較列表中的字典

我有兩個包含字典的列表,大部分這些鍵都是一樣的。請參閱下面的一個簡單的例子:

x1 = [{'a':1,'b':"cat"},{'a':2,'b':"parrot"},...] 
x2 = [{'a':2,'b':"dog"},{'a':1,'b':"fish"},...] 

現在我想比較基於一鍵即鍵的值,但兩個列表的長度不會永遠是相同的。如果存在相應字典,則關鍵字a將始終存在於兩個字典中,即x1[0]['a'] == x2[1]['a']

我怎麼能比較這些基於密鑰a的字典,以便我可以首先丟棄x1那些不出現在x2,反之亦然。然後確定兩個詞典中是否出現某些值,然後將其記錄在數據庫中,這裏沒有必要。

我在想的是將這些字典組合成一個基於關鍵字a的列表中的元組。然後遍歷這個並比較這些值。這可能不是最好的辦法,所以如果你有更好的想法,請隨時取消。 :)

[編輯]

我沒有清楚地說明問題,我很抱歉。我希望做的是;首先:匹配基於密鑰a的字典。第二:忽略那些不匹配的(關鍵字a)。第三:比較密鑰b。第四:根據b的比較更新數據庫。

謝謝所有已經回答的人。

我的答案是這樣的:

「我想到了一個列表比較可能做精,以構建一個包含從x1的字典,從x2字典對應的元組,然後通過每個元組比較鍵B迭代但我認爲這可能太慢了。「

我不認爲這是做的非常好的方式。所以這就是爲什麼我在這裏:)

謝謝你提前。

+2

請描述你想要的結果。比較所有這些對比較容易,但是所有這些比較的結果應該如何處理? – Alfe

+1

如果列表不是同樣長的(如你所說的那樣),會發生什麼? – Alfe

+1

你能解釋一下這個陳述嗎? '如果有對應的字典,關鍵字a將永遠存在於兩個字典中'。你的例子不是很有幫助。 – Abhijit

回答

1

如果我正確理解你想要的東西是這樣的,它通過將'a'值作爲關鍵字將這兩個列表轉換爲字典來工作。它假定每個列表中沒有「a」值的複製,並返回一個字典,其中'a'值作爲關鍵字,配對的'b'的元組作爲值返回。

x1 = [{'a':1,'b':"cat"}, {'a':2,'b':"parrot"}, {'a': 3, 'b': 'dog'}] 
x2 = [{'a':2,'b':"dog"}, {'a':1,'b':"fish"}] 
x1_d = {d['a']: d['b'] for d in x1} 
x2_d = {d['a']: d['b'] for d in x2} 
matched_keys = set(x1_d) & set(x2_d) 
result = {key: (x1_d[key], x2_d[key]) for key in matched_keys} 
print result  # {1: ('cat', 'fish'), 2: ('parrot', 'dog')} 

可能有更快的方式做到這一點,但也許你可以確認這是否是你正在尋找的結果。

1

如果你只需要調用

[ a['a'] == b['a'] for a, b in zip(x1, x2) ] 

你會得到比較結果的列表。如果列表不等長,則較短將確定比較的對數。

注意,結果將是布爾值(TrueFalse)的列表。如果你想要其他東西,請更清楚地說明這一點。

2

我真的不明白你的比較,但我猜你想要的是

len(x1)==len(x2) and all(a['a']==b['a'] for (a, b) in zip(x1, x2)) 

或等價(但效率較低),

[a['a'] for a in x1] == [b['a'] for b in x2] 
+0

這是暗示並不是所有的'dict's都會包含關鍵字'a',但是如果其中一個會這樣做的話......所以第二個可能會有例外...... –

+0

@JonClements我明白了。我們可以用'[a.get('a')代替in x1] == [b.get('a')for b in x2]'。如果'dict'不包含關鍵字'a',那麼我們在兩個列表中都會得到兩個'None'。 – chys

1
x1 = [{'a':1,'b':"cat"},{'a':2,'b':"parrot"}] 
x2 = [{'a':2,'b':"dog"},{'a':1,'b':"fish"},{'a':3},{'a':2}] 

[(_x2,_x2['a'] in [_x1['a'] for _x1 in x1]) for _x2 in x2] 
[({'a': 2, 'b': 'dog'}, True), 
({'a': 1, 'b': 'fish'}, True), 
({'a': 3}, False), 
({'a': 2}, True)] 

此代碼工作中一個方向。你可以將它適應於兩個方向,或者只是使用它兩次。