किसी आइटम को किसी ऐसे शब्दकोश से निकालें जब उसकी कुंजी अज्ञात हो


112

किसी शब्द को मूल्य से शब्दकोष से हटाने का सबसे अच्छा तरीका क्या है, जब आइटम की कुंजी अज्ञात है? यहाँ एक सरल तरीका है:

for key, item in some_dict.items():
    if item is item_to_remove:
        del some_dict[key]

क्या बेहतर तरीके हैं? क्या इसे पुनरावृत्त करते समय शब्दकोष से म्यूटिंग (हटाना आइटम) में कुछ भी गलत है?


1
म्यूट करते समय तानाशाही पर रोक लगाने के लिए रेखांकित करने का कारण यह है क्योंकि आंतरिक रूप से पुनरावृत्ति के लिए एक आदेश है, यदि आप कुंजियों को म्यूट करते हैं, तो आदेश को कम आंका जाएगा, जिसके परिणामस्वरूप अज्ञात व्यवहार होता है।
स्पेक्ट्रल

जवाबों:


92

ध्यान रखें कि आप वर्तमान में ऑब्जेक्ट आइडेंटिटी के लिए परीक्षण कर रहे हैं ( isकेवल रिटर्न Trueयदि दोनों ऑपरेंड को मेमोरी में एक ही ऑब्जेक्ट द्वारा दर्शाया जाता है - यह हमेशा दो ऑब्जेक्ट के साथ ऐसा नहीं है जो बराबर की तुलना करता है ==)। यदि आप उद्देश्य से ऐसा कर रहे हैं, तो आप अपने कोड को फिर से लिख सकते हैं

some_dict = {key: value for key, value in some_dict.items() 
             if value is not value_to_remove}

लेकिन यह वह नहीं हो सकता जो आप चाहते हैं:

>>> some_dict = {1: "Hello", 2: "Goodbye", 3: "You say yes", 4: "I say no"}
>>> value_to_remove = "You say yes"
>>> some_dict = {key: value for key, value in some_dict.items() if value is not value_to_remove}
>>> some_dict
{1: 'Hello', 2: 'Goodbye', 3: 'You say yes', 4: 'I say no'}
>>> some_dict = {key: value for key, value in some_dict.items() if value != value_to_remove}
>>> some_dict
{1: 'Hello', 2: 'Goodbye', 4: 'I say no'}

तो आप शायद !=इसके बजाय चाहते हैं is not


2
क्या यह एक शब्दकोश सम्पीडन है? उन्हें कब जोड़ा गया?
बटंस .४०

4
आप some_dict.iteritems()यहां उपयोग कर सकते हैं और पठनीयता के लिए अलग-अलग लाइनों पर बयान forऔर ifविवरण डाल सकते हैं
jfs

3
मेरा मानना ​​है कि पायथन 2.7 में डिक्शनरी कॉम्प्रिहेंशन जोड़े गए थे।
मिथ्रंदी

2
@ जेएफ सेबस्टियन: मैं पायथन 3 पर हूं, और iteritemsअब हूं items। पायथन 2.7 में, iteritems()वास्तव में बेहतर है।
टिम पीत्ज़ेकर

1
@ Buttons840 उन्हें PEP 274 या डिक्शनरी डिस्प्ले में तानाशाह की समझ कहा जाता है । जैसा कि पीईपी का कहना है कि वे 2.7 में जोड़े गए थे । वैकल्पिक रूप से आप dict()एक उपयुक्त जनरेटर अभिव्यक्ति के साथ फ़ीड कर सकते हैं , जो 2.4 है। मेटा: सामान बाहर खोजने के लिए यहाँ peps ब्राउज़ कर सकते हैं।
n611x007

120

dict.pop(key[, default])विधि आप आइटम हटाने के लिए जब आप कुंजी पता अनुमति देता है। यह कुंजी पर मूल्य लौटाता है यदि यह आइटम को हटा देता है अन्यथा यह वापस आ जाता है जैसा कि पारित किया गया है defaultडॉक्स देखें । '

उदाहरण:

>>> dic = {'a':1, 'b':2}
>>> dic
{'a': 1, 'b': 2}
>>> dic.pop('c', 0)
0
>>> dic.pop('a', 0)
1
>>> dic
{'b': 2}

4
ओपी ने पूछा कि चाबी कब अज्ञात है
nmz787


42

डेल और पॉप के बीच एक सरल तुलना () :

import timeit
code = """
results = {'A': 1, 'B': 2, 'C': 3}
del results['A']
del results['B']
"""
print timeit.timeit(code, number=100000)
code = """
results = {'A': 1, 'B': 2, 'C': 3}
results.pop('A')
results.pop('B')
"""
print timeit.timeit(code, number=100000)

परिणाम:

0.0329667857143
0.0451040902256

तो, डेल पॉप () से तेज है ।


6
हालाँकि, प्रदर्शन अंतर बहुत अच्छा नहीं है, और यदि आप एक अपवाद को बढ़ाने से बचना चाहते हैं, तो आप एक दूसरा तर्क प्रदान कर सकते हैं pop()(जैसा कि @ n-1-1 ऊपर करता है) - जो delऑपरेटर के लिए कोई विकल्प नहीं है ।
एलेक्स दुपॉय

1
सवाल के अनुशीलन, लेकिन मैं भी समझने के लिए संघर्ष कर रहा था timeit। इस स्पष्ट उदाहरण के लिए धन्यवाद।
एडम_जी

ओपी ने पूछा कि चाबी कब अज्ञात है। यह उत्तर मानता है कि कुंजी ज्ञात है।
जीन-फ्रांकोइस कॉर्बेट

7

items()एक सूची देता है, और यह वह सूची है जिसे आप पुनरावृत्त कर रहे हैं, इसलिए लूप में हुक्म को म्यूट करने से यहां कोई फर्क नहीं पड़ता। यदि आप iteritems()इसके बजाय उपयोग कर रहे थे , तो लूप में हुक को म्यूट करना समस्याग्रस्त होगा , और इसी तरह viewitems()पायथन 2.7 में।

मैं मूल्य से एक तानाशाह से आइटम हटाने के लिए एक बेहतर तरीका नहीं सोच सकता।


7

मैं उन चाबियों की एक सूची बनाऊंगा जिन्हें हटाने की आवश्यकता है, फिर उन्हें हटा दें। यह सरल है, कुशल है और साथ-साथ चलने और ताना-बाना बदलने के बारे में किसी भी समस्या से बचा जाता है।

keys_to_remove = [key for key, value in some_dict.iteritems()
                  if value == value_to_remove]
for key in keys_to_remove:
    del some_dict[key]

ओपी ने पूछा कि चाबी कब अज्ञात है। यह उत्तर मानता है कि कुंजी ज्ञात है।
जीन-फ्रांकोइस कॉर्बेट


1
y={'username':'admin','machine':['a','b','c']}
if 'c' in y['machine'] : del y['machine'][y['machine'].index('c')]

0

आपके द्वारा प्रस्तावित करते समय, शब्दकोश से आइटम हटाने के साथ कुछ भी गलत नहीं है। एक ही समय में एक ही शब्दकोश का उपयोग करते हुए कई थ्रेड्स के बारे में सावधान रहें, जिसके परिणामस्वरूप KeyError या अन्य समस्याएं हो सकती हैं।

बेशक, http://docs.python.org/library/stdtypes.html#typesmapping पर डॉक्स देखें


for k,v in d.iteritems(): del d[k]दे देंगे RuntimeError: dictionary changed size during iteration। देखिए मैथृंडी का स्पष्टीकरण
बटंस Butt४०

1
बेशक, d.iteritems () यह नहीं है कि मूल पोस्टर कैसे परेशान कर रहा है, और यह नहीं कि मैं अपने उत्तर में क्या उल्लेख कर रहा था।
ठाणे गान

0

यह है कि मैं यह कैसे करेंगे।

for key in some_dict.keys():
    if some_dict[key] == item_to_remove:
        some_dict.pop(key)
        break
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.