2014-08-28 13 views
9

मेरे पास शब्दकोशों की दो सूचियां हैं और मैं उनके बीच अंतर ढूंढना चाहता हूं (यानी पहली सूची में मौजूद है लेकिन दूसरा नहीं, और दूसरी सूची में क्या मौजूद है लेकिन पहली सूची नहीं है)।शब्दकोशों की दो सूचियों के बीच अंतर कैसे प्राप्त करें?

मुद्दा यह है कि यह शब्दकोशों

a = [{'a': '1'}, {'c': '2'}] 
b = [{'a': '1'}, {'b': '2'}] 

set(a) - set(b) 

परिणाम की एक सूची है है

TypeError: unhashable type: 'dict' 

वांछित परिणाम:

{'c': '2'} 

मैं कैसे यह पूरा करते हैं?

+1

क्या आपके शब्दकोश वास्तव में केवल एक आइटम हैं? यदि हां, तो सूची को एक शब्दकोश में बनाने के लिए और अधिक समझदारी नहीं होगी? – cmd

+0

नहीं, वे कई आइटम हैं (लगभग 15 प्रत्येक संभवतः) और यह प्रत्येक सूची में 3000 से 1000 डिकटिनरी की एक सूची होगी – Chris

+0

क्या आप अपना वांछित परिणाम देख सकते हैं। आपकी परिभाषा के मुताबिक आप एक [सममित अंतर] (http://en.wikipedia.org/wiki/Symmetric_difference) देख रहे हैं –

उत्तर

11

आप अगर यह सूची में है देखने के लिए in ऑपरेटर का उपयोग कर सकते

a = [{'a': '1'}, {'c': '2'}] 
b = [{'a': '1'}, {'b': '2'}] 

>>> {'a':'1'} in a 
True 
>>> {'a':'1'} in b 
True 

>>> [i for i in a if i not in b] 
[{'c': '2'}] 
0

भी कर सकते हैं आप के साथ filter एक lambda:

:

आप प्रत्येक सूची में अलग-अलग आइटम चाहते हैं

print filter(lambda x: x not in b,a) + filter(lambda x: x not in a,b) 

[{'c': '2'}, {'b': '2'}] 

या filter(lambda x: x not in b,a)a में तत्व प्राप्त करने के लिए, लेकिन b 0 में नहीं आप स्मृति में dicts की पूरी सूची बनाने के लिए नहीं करना चाहतीयदि आप उपयोग कर सकते हैं itertools.ifilter

from itertools import ifilter 

diff = ifilter(lambda x: x not in b,a) 

तो बस diff से अधिक पुनरावृति:

for uniq in diff: 
    print uniq 
3

मैं अंतर प्राप्त करना चाहते हैं उनके बीच (यानी क्या पहली सूची में मौजूद है, लेकिन दूसरा नहीं, और क्या दूसरी सूची में मौजूद नहीं है, लेकिन पहली सूची)

अपनी परिभाषा के अनुसार

, आप एक Symmetric difference की तलाश:

>>> import itertools 

>>> a = [{'a': '1'}, {'c': '2'}] 
>>> b = [{'a': '1'}, {'b': '2'}] 
>>> intersec = [item for item in a if item in b] 
>>> sym_diff = [item for item in itertools.chain(a,b) if item not in intersec] 

>>> intersec 
[{'a': '1'}] 
>>> sym_diff 
[{'c': '2'}, {'b': '2'} 

वैकल्पिक रूप से (plain difference का उपयोग करके आपके उदाहरण में दिए गए अनुसार):

>>> a_minus_b = [item for item in a if item not in b] 
>>> b_minus_a = [item for item in b if item not in a] 
>>> sym_diff = list(itertools.chain(a_minus_b,b_minus_a)) 

>>> a_minus_b 
[{'c': '2'}] 
>>> b_minus_a 
[{'b': '2'}] 
>>> sym_diff 
[{'c': '2'}, {'b': '2'}] 
+0

इसे उत्तर में से एक में संदर्भित किया गया था, लेकिन मेरा मानना ​​है कि यह वही है जो ओपी चाहता था .. .so +1। एक प्रश्न, क्या आप 'itertools.chain' का उपयोग करने के बजाय' a_minis_b' और 'b_minus_a' को' sym_diff' में जोड़ने के लिए '+ 'ऑपरेटर का उपयोग नहीं कर सकते? –

+1

@ खलीलमोर- خليلعمور हाँ आप कर सकते हैं। लेकिन 'itertools.chain() 'का उपयोग करके आपको इसका उपयोग करने से पहले स्मृति में परिणामी सूची बनाने की आवश्यकता नहीं है। "बड़ी" सूचियों के लिए विशेष रूप से महत्वपूर्ण है। हालांकि, इसके साथ थोड़ा और संगत होने के लिए, मुझे यहां एक सूची समझ के बजाय जेनरेटर का उपयोग करना चाहिए था: 'a_minus_b = (यदि आइटम में आइटम के लिए आइटम बी में नहीं है)'।लेकिन यह नमूना कोड में और अधिक मुश्किल होगा, क्योंकि जब आप उनका उपयोग करते हैं तो जनरेटर आइटम का उपभोग करता है। –

+0

अहह ... मैं देखता हूं ... तो यह स्मृति अनुकूलन के लिए था, क्या आप मुझे जेनरेटर के साथ एक उदाहरण दिखा सकते हैं, हो सकता है कि आप अपने उत्तर को संपादित कर सकें, अगर आप करेंगे? –

संबंधित मुद्दे