2012-06-22 14 views
12

मैं एक सूची है कि इस तरह दिखता है:अजगर - एक शब्दकोश की एक सूची और चाबी के बीच चौराहे

l1 = ['200:200', '90:728'] 

मैं एक शब्दकोश है कि इस तरह दिखता है:

d1 = {'200:200':{'foo':'bar'},'300:300':{'foo':'bar'}} 

मैं प्राप्त करने की आवश्यकता तानाशाही को फ़िल्टर करें जहां केवल चाबियां एल 1 में हों। संक्षेप में एक सूची के एक चौराहे और एक dict की चाबी

result = {'200:200':{'foo':'bar'}} 

जबकि dict की उपधारा लौटने: dict इस तरह दिखना चाहिए।

मैं इसे कुशलतापूर्वक कैसे कर सकता हूं जहां बड़े सेट के लिए समय मुद्दा है?

धन्यवाद

उत्तर

23

आप नीचे दिए गए कोड का उपयोग कर सकते हैं:

keys = set(l1).intersection(set(d1.keys())) 
result = {k:d1[k] for k in keys} 

संपादित करें: टिप्पणीकर्ताओं का सुझाव के रूप में आप के साथ पहली पंक्ति, पायथन 2.x में जगह ले सकता है:

keys = set(l1).intersection(d1) 

और पायथन 3.x:

keys = d1.keys() & l1 
पहले एक सेट में

result = dict([(k,d1[k]) for k in l1 if k in d1]) 

आप डुप्लिकेट चाबी निकालने के बारे में चिंतित हैं, एल 1 बनाना:

+0

ध्यान दें कि 3.x में, एक शब्दकोश दृश्य सेट-जैसा है, इसलिए आपको इसे 'set()' में लपेटने की आवश्यकता नहीं है। वास्तव में, 3.x में, पूरी शीर्ष पंक्ति 'कुंजी = d1.keys() और l1' हो सकती है। –

+1

@ लैटवेयर आपको 2.x या तो – jamylak

+4

में सेट में डालने की आवश्यकता नहीं है, इसकी भी आवश्यकता नहीं है(), 'set (l1) .intersection (d1) ' – georg

0

आप dict निर्माता में एक सूची समझ का उपयोग कर सकते

result = dict([(k,d1[k]) for k in set(l1) if k in d1]) 
+0

एक कुंजी 'd1' में नहीं हो सकती है। यह काम नहीं करेगा। –

+0

यह भी ध्यान दें कि आप मेरे समाधान में जैसे ही जन जनरेटर अभिव्यक्ति कर सकते हैं। तो '{k: v के लिए v, v arr में}}। डुप्लिकेट से निपटने का भी इसका लाभ है। – JPvdMerwe

+0

@JPvdMerwe यह एक श्रोताओं की समझ है, न कि एक जन जनरेटर अभिव्यक्ति - जेनरेटर अभिव्यक्ति आलसी हैं, एक धक्का समझ नहीं है। –

4

3.x में,

>>> {k: d1[k] for k in (d1.keys() & l1)} 
{'200:200': {'foo': 'bar'}} 

के तहत 2.7, आप dict.viewkeys() उपयोग कर सकते हैं इस कार्यक्षमता से बनाना: यह रूप में सरल रूप में हो सकता

>>> {k: d1[k] for k in (d1.viewkeys() & l1)} 
{'200:200': {'foo': 'bar'}} 

2.x के पुराने संस्करणों के तहत, यह एक बालक और अधिक वर्बोज़ है:

>>> {k: d1[k] for k in (set(d1).intersection(l1))} 
{'200:200': {'foo': 'bar'}} 
+0

मैंने दस्तावेज़ों की जांच की। ऐसा प्रतीत होता है कि 'व्यूकी)() '2.7 में उपलब्ध है, न केवल 2.7.3। यह पाइथन की मेरी प्रति में दिखाई देता है 2.7.1 – JPvdMerwe

+0

@JPvdMerwe जानना अच्छा है, अपडेट किया गया। –

3

प्रत्येक समाधान प्रदर्शन के बारे में सुनिश्चित नहीं हैं, लेकिन मैं करना होगा:

{k: v for k, v in d1.items() if k in l1} 
+2

यह तब भी काम करेगा जब एल 1 का सदस्य डी 1 में कुंजी नहीं है, जो कई अन्य विफल हो जाएंगे। –

0

परिभाषित कुशल। वैसे भी मैं क्या करूँगा। अगर यह बहुत धीमी थी तो शायद मैं इसे साइथन में ले जाऊंगा।

s1 = set(l1) 
s2 = set(d1.keys()) 
s3 = s1 & s2 
# now you can access d1 using only keys in s3, or construct a new dict if you like 
d2 = dict([(k,d1[k]) for k in s3]) 
0

यदि स्मृति आवंटन और विलोपन इस प्रक्रिया को बहुत लंबा ले रहा है, तो बचाव के लिए itertools।

import itertools 
result = {dict_key:d1[dict_key] for dict_key in itertools.ifilter(lambda list_item: list_item in d1, l1) } 

यह अनावश्यक रूप से एक नया संग्रह के लिए स्मृति को आबंटित नहीं है, और एल 1 आसानी से एक इटरेटर बजाय की एक सूची हो सकता है।

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