2013-02-11 13 views
5

मैं एक शब्दकोश है अजगर शब्दकोश से खाली सूचियों को हटाने के लिए एक सुरुचिपूर्ण रास्तापायथन:</p> <pre><code>default = {'a': ['alpha'], 'b': ['beta','gamma'], 'g': []} </code></pre> <p>मैं के रूप में खाली मूल्यों को खत्म करना चाहते हैं: के रूप में

default = {'a': ['alpha'], 'b': ['beta','gamma']} 

मैं एक समारोह में लिखा था (निम्नलिखित एक उदाहरण वेब पर मिल)

def remove_empty_keys(d): 
    for k in d.keys(): 
     try: 
      if len(d[k]) < 1: 
       del[k] 
     except: 
      pass 
     return(d) 

मैं निम्नलिखित प्रश्न हैं:

1- मैं गलती क्यों यह हमेशा निम्नलिखित रिटर्न नहीं मिला -

remove_empty_keys(default) 
{'a': ['alpha'], 'b': ['beta'], 'g': []} 

2- वहाँ एक अंतर्निहित समारोह को खत्म/एक बनाने के बिना पायथन शब्दकोश से अशक्त/कोई नहीं/खाली मान हटाना है मूल शब्दकोश की प्रतिलिपि?

+1

आपका प्रश्न खाली सूचियों के साथ 'कोई नहीं' के विचार को मिलाता प्रतीत होता है। यह समझना मुश्किल बनाता है। –

+0

शायद यह कहने का एक बेहतर तरीका होगा "क्या एक शब्दकोश से झूठे मूल्यों को खत्म करने के लिए कोई फ़ंक्शन है" – mgilson

+0

आपकी 'कोशिश करें ... सिवाय इसके कि' खंड आपके द्वारा स्वयं की त्रुटियों को छिपाने के अलावा कोई उद्देश्य नहीं प्रदान करता है। यदि आप वास्तव में कोशिश/छोड़ने का उपयोग करना चाहते हैं, तो आपको हमेशा अपवाद (ओं) निर्दिष्ट करना चाहिए जो आप उम्मीद करते हैं (इस मामले में KeyError)। इस तरह, वे अनजाने में असंबद्ध बग छिपाएंगे। लेकिन इस मामले में, जब तक कि समानांतर धागे में कोड नहीं है जो 'डी' को संशोधित कर रहा है, आपको कभी भी एक महत्वपूर्ण त्रुटि नहीं मिलेगी क्योंकि 'k' * *' d' में होना चाहिए क्योंकि इसे 'd.keys() द्वारा वापस किया गया था '। –

उत्तर

8

अपने फ़ंक्शन को ठीक करने के लिए, del[k] से del d[k] बदलें। किसी शब्दकोश से मूल्यों को हटाने के लिए कोई फ़ंक्शन नहीं है।

आप क्या कर रहे हैं वेरिएबल k को हटा रहा है, शब्दकोश को बिल्कुल नहीं बदल रहा है। यही कारण है कि मूल शब्दकोश हमेशा वापस आ जाता है।

फिर से लिखा, अपने कार्य लग सकता है जैसे:

def remove_empty_keys(d): 
    for k in d.keys(): 
     if not d[k]: 
      del d[k] 

इसका मतलब यह है कि आप दोनों खाली सूची और None मूल्यों को खत्म करना चाहते हैं, और वास्तव में एक "गलत" मूल्य के साथ किसी भी आइटम को हटा।

+0

पायथन 2 में, 'd.keys()' (जो एक सूची थी) पर पुनरावृत्ति करना लूप में मानों को हटाना संभव बनाता है। पायथन 3 में, 'd.keys()' है [lazier] (https://docs.python.org/3/library/stdtypes.html#dict-views)। 'सूची (डी)' के बजाय Iterate, या [@ mgilson के उत्तर] में एक नया शब्दकोश बनाएं (https://stackoverflow.com/एक/14813423/1307866) – tiwo

6

इसके लिए कोई अंतर्निहित (AFAIK) नहीं है, लेकिन यदि आप एक dict समझ के साथ आसानी से यह कर सकते हैं:

new_dict = {k:v for k,v in original_dict.items() if v} 

आप (पूर्व 2.7 dict comprehensions के बिना) अजगर के एक पुराने संस्करण के साथ फंस रहे हैं, आप ताना कन्स्ट्रक्टर का उपयोग कर सकते हैं:

new_dict = dict((k,v) for k,v in original_dict.items() if v) 

ध्यान दें कि यह स्थान (आपके दूसरे प्रश्न के अनुसार) में संचालित नहीं होता है। करने के लिए सूची की तरह और शब्दकोशों टुकड़ा काम का समर्थन नहीं करते, इसलिए सबसे अच्छा * क्या तुम सच में यह सब जगह में करवाने के लिए क्या कर सकते हैं:

new_dict = {k:v for k,v in original_dict.items() if v} 
original_dict.clear() 
original_dict.update(new_dict) 

* पाठ्यक्रम की अवधि "सर्वश्रेष्ठ" पूरी तरह से व्यक्तिपरक है।

4

आप dict समझ का उपयोग कर सकते हैं: -

>>> default = {'a': ['alpha'], 'b': ['beta','gamma'], 'g': []} 

>>> {key: value for key, value in default.iteritems() if value} 
{'a': ['alpha'], 'b': ['beta', 'gamma']} 
+0

समस्या उस नियम को संशोधित नहीं कर रही है जब आप इसे पुन: सक्रिय कर रहे हैं - मुझे वास्तव में लगता है कि यह ठीक हो सकता है (हालांकि मुझे उस पर उद्धरण न दें)। यह है कि ओपी 'डेल डी [के] 'के बजाय' डेल [के]' कर रहा है। ऐसा लगता है कि पहला फॉर्म एक सूची बना रहा है और फिर इसे हटा रहा है (हालांकि मैं इसके बारे में गलत हो सकता हूं क्योंकि 'del' एक कथन है ... – mgilson

+0

@mgilson। हाँ बस उस पर ध्यान दिया। मैं उस रेखा को हटा दूंगा। –

4
dict((k, v) for k, v in default.iteritems() if v) 

यह सभी आइटम जो रिक्त स्ट्रिंग, खाली dict/टपल/सूची नहीं हैं फिल्टर।

1

Michael's answer सही है।

वापस कदम है, तो आप बिल्कुल उन खाली सूचियां बनाते समय से बचने के लिए सक्षम हो सकता है collections.defaultdict(list)

>>> import collections 
>>> d = collections.defaultdict(list) 
>>> d 
defaultdict(<type 'list'>, {}) 
>>> d["hobbits"].append("Frodo") 
>>> d["hobbits"].append("Sam") 
>>> d 
defaultdict(<type 'list'>, {'hobbits': ['Frodo', 'Sam']}) 
1

एक और विकल्प के उपयोग के द्वारा किया जाता है निम्नलिखित (एक नई शब्दावली बनाने के बिना):

for e in [k for k,v in default.iteritems() if len(v) == 0]: default.pop(e) 
संबंधित मुद्दे

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