2009-07-31 11 views
5

ठीक है, मैं अटक कर रहा हूँ, यहां से कुछ मदद की जरूरत है ...पाइथन में कुंजी/मूल्यों के आधार पर शब्दकोशों को फ़िल्टर करना और उप-शब्दकोश बनाना?

मैं इस तरह एक मुख्य शब्दकोश मिल गया है, तो:

data = [ {"key1": "value1", "key2": "value2", "key1": "value3"}, 
{"key1": "value4", "key2": "value5", "key1": "value6"}, 
{"key1": "value1", "key2": "value8", "key1": "value9"} ] 

अब, मुझे लगता है कि शब्दकोश के माध्यम से पहले से ही जाने की जरूरत है

for datadict in data: 
    for key, value in datadict.items(): 
    ...filter the data... 

अब, अगर उन मूल्यों मुझे लगता है कि एक ही पाश किसी भी तरह में और होगा (यदि संभव हो तो ... यदि नहीं, तो सुझाव है कि विकल्प कृपया) कुछ कुंजी के मूल्यों के लिए जाँच,: डेटा के कुछ, यानी फ़ॉर्मेट करने के लिए मेरे प्रीसेट से मेल खाते हैं तो मैं उस पूरी सूची को किसी अन्य शब्दकोश में जोड़ दूंगा, इस प्रकार effec छोटे कुंजीपटल बनाने के साथ-साथ मैं कुछ मुख्य कुंजी और मूल्यों के आधार पर इस मुख्य शब्दकोश के साथ-साथ जाता हूं?

तो, चलो कहते हैं कि मैं सभी सूचियों के साथ सब-शब्दकोश, जिसमें कुंजी 1 "मान 1" का मूल्य है, जो ऊपर की सूची के लिए मुझे कुछ इस तरह देना होगा है बनाना चाहते हैं, करते हैं:

subdata = [ {"key1": "value1", "key2": "value2", "key1": "value3"}, 
{"key1": "value1", "key2": "value8", "key1": "value9"} ] 
+1

"इस तरह का एक मुख्य शब्दकोश" सही नहीं है। आपके पास शब्दकोशों की एक सूची है। –

+0

और शब्दकोश कुंजी अद्वितीय हैं, इसलिए आप डुप्लिकेट कुंजी के साथ एक शब्दकोश नहीं बना सकते हैं: {"key1": "value1", "key2": "value2", "key1": "value3"}; परिणाम {'key2': 'value2', 'key1': 'value3'} है। यदि आप वास्तव में डुप्लिकेट चाहते हैं, तो आपको एक सूची की आवश्यकता होगी, इसलिए समग्र संरचना सूचियों की एक सूची होगी या शब्दकोश मानों को टुपल्स या सूचियां होनी चाहिए। –

उत्तर

9

यहां ऐसा करने का एक बहुत अच्छा तरीका नहीं है। नतीजा एक जनरेटर है, लेकिन यदि आप वास्तव में एक सूची चाहते हैं तो आप इसे list() पर कॉल के साथ घेर सकते हैं। ज्यादातर इससे कोई फर्क नहीं पड़ता।

भविष्यवाणी एक ऐसा फ़ंक्शन है जो प्रत्येक कुंजी/मूल्य जोड़ी का निर्णय लेता है यदि सूची में कोई शब्दकोश इसे काटने जा रहा है। डिफ़ॉल्ट एक सब स्वीकार करता है। यदि शब्दकोश मिलान में कोई के/वी-जोड़ी नहीं है तो इसे खारिज कर दिया जाता है। मुद्दों की

def filter_data(data, predicate=lambda k, v: True): 
    for d in data: 
     for k, v in d.items(): 
       if predicate(k, v): 
        yield d 


test_data = [{"key1":"value1", "key2":"value2"}, {"key1":"blabla"}, {"key1":"value1", "eh":"uh"}] 
list(filter_data(test_data, lambda k, v: k == "key1" and v == "value1")) 
# [{'key2': 'value2', 'key1': 'value1'}, {'key1': 'value1', 'eh': 'uh'}] 
+2

"इतना सुंदर नहीं"? सहमत नहीं हैं। यह बहुत अच्छा है। –

+0

धन्यवाद :)। मुझे लगता है कि सीढ़ी के मामले के काम जैसे बदसूरत हैं। – Skurmedel

+1

@ स्कुरमेडेल: आपका कार्य सुरुचिपूर्ण है और यह देखना आसान है कि यह सरल चरणों में नौकरी कैसे करता है; यह पाठकों को उनके सिर में एक जटिल एक-लाइनर का विश्लेषण करने के लिए बचाता है। –

1

जवाब बहुत आसान है, इसलिए मुझे लगता है कि हम कुछ जानकारी खो रहे हैं। वैसे भी:

result = [] 
for datadict in data: 
    for key, value in datadict.items(): 
     thefiltering() 

    if datadict.get('matchkey') == 'matchvalue': 
     result.append(datadict) 

इसके अलावा, आप "मुख्य शब्दकोश" एक शब्दकोश नहीं बल्कि एक सूची है। बस उस को स्पष्ट करना चाहता था।

3

नेट पहले से ही अन्य टिप्पणी और उत्तर में बताया (एक जैसे अनेक कुंजी एक dict में नहीं किया जा सकता, आदि आदि) है, तो यहां मैं यह कर करेंगे:

def select_sublist(list_of_dicts, **kwargs): 
    return [d for d in list_of_dicts 
      if all(d.get(k)==kwargs[k] for k in kwargs)] 

subdata = select_sublist(data, key1='value1') 
0

Skurmedal के जवाब से प्रेरित होकर, मैंने नेस्टेड शब्दकोशों के डेटाबेस के साथ काम करने के लिए इसे एक पुनरावर्ती योजना में विभाजित किया। इस मामले में, एक "रिकॉर्ड" ट्रंक पर subdictionary है। भविष्यवाणी यह ​​निर्धारित करती है कि हम किस रिकॉर्ड के बाद हैं - वे जो कुछ (कुंजी, मूल्य) जोड़ी से मेल खाते हैं जहां ये जोड़े गहराई से घोंसला हो सकते हैं।

def filter_dict(the_dict, predicate=lambda k, v: True): 
    for k, v in the_dict.iteritems(): 
     if isinstance(v, dict) and _filter_dict_sub(predicate, v): 
      yield k, v 

def _filter_dict_sub(predicate, the_dict): 
    for k, v in the_dict.iteritems(): 
     if isinstance(v, dict) and filter_dict_sub(predicate, v): 
      return True 
     if predicate(k, v): 
      return True 
    return False 

चूंकि यह एक जनरेटर है, तो आप dict(filter_dict(the_dict)) साथ रैप करने के लिए फ़िल्टर किए गए शब्दकोश प्राप्त करने के लिए आवश्यकता हो सकती है।

0

यह एक पुराने सवाल है, लेकिन किसी कारण से कोई एक लाइनर वाक्य रचना जवाब है:

{ k: v for k, v in <SOURCE_DICTIONARY>.iteritems() if <CONDITION> } 

उदाहरण के लिए:

Source dictionary: {1: 'a', 2: 'b', 3: 'c', 4: 'd'} 
Filtered dictionary: {2: 'b', 4: 'd'} 
:

src_dict = { 1: 'a', 2: 'b', 3: 'c', 4: 'd' } 
predicate = lambda k, v: k % 2 == 0 
filtered_dict = { k: v for k, v in src_dict.iteritems() if predicate(k, v) } 

print "Source dictionary:", src_dict 
print "Filtered dictionary:", filtered_dict 

निम्नलिखित उत्पादन का उत्पादन होगा

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