2010-06-19 17 views
6
में dict से कुछ कुंजी को हटाने का सबसे तेज तरीका

मैं सबसे तेजी से अधिकांश के लिए देख रहा हूँ/एक अजगर dictअजगर

यहाँ में कुछ कुंजी को हटाने का प्रभावी तरीका कुछ विकल्प हैं

for k in somedict.keys(): 
    if k.startswith("someprefix"): 
     del somedict[k] 

या

dict((k, v) for (k, v) in somedict.iteritems() if not k.startswith('someprefix')) 

तर्कसंगत रूप से पहला स्निपेट छोटे डिक्ट्स पर तेज़ होना चाहिए, यह एक निर्देश की एक प्रति नहीं बनाता है लेकिन सभी चाबियों की एक सूची बनाता है, हालांकि डबल लुकअप और टोक पुनर्निर्माण समय लेने वाला है। जबकि दूसरा बड़ा डिक्ट्स पर तेज़ है, लेकिन 2x अधिक मेमोरी की आवश्यकता है। मैंने कुछ छोटे बेंचमार्क में अपनी धारणा की जांच की है।

कुछ भी तेज़?

+0

@Adam: नहीं, आप नहीं कर सकते। आप जिस उपकरण को फिर से चालू कर रहे हैं उससे आइटम जोड़ या हटा नहीं सकते हैं। –

+0

एक त्रिभुज का प्रयोग करें। ___ – kennytm

+0

@Ignacio: धन्यवाद, हटाई गई टिप्पणी। – bernie

उत्तर

9

यदि dict पर्याप्त पर्याप्त है, तो यह इसके बजाय एक संपूर्ण नया निर्देश उत्पन्न करने के लिए समझ में आता है।

dict((k, v) for (k, v) in somedict.iteritems() if not k.startswith('someprefix')) 
+0

धन्यवाद, मेरा पहला समाधान बिल्कुल तुम्हारा जैसा था, बेंचमार्क के लिए दिलचस्प जो तेज़ है। – HardQuestions

11

इतना ही नहीं del अधिक आसानी से समझा है, लेकिन यह pop() की तुलना में थोड़ा तेजी से लगता है:

$ python -m timeit -s "d = {'f':1,'foo':2,'bar':3}" "for k in d.keys():" " if k.startswith('f'):" " del d[k]" 
1000000 loops, best of 3: 0.733 usec per loop 

$ python -m timeit -s "d = {'f':1,'foo':2,'bar':3}" "for k in d.keys():" " if k.startswith('f'):" " d.pop(k)" 
1000000 loops, best of 3: 0.742 usec per loop 

संपादित करें: कैसे इस बेंच मार्किंग करने के निर्देशों प्रदान करने के लिए एलेक्स मार्टेली के लिए धन्यवाद। उम्मीद है कि मैं कहीं भी फिसल गया नहीं है।

पहले मापने के समय नकल के लिए आवश्यक: की नकल की dict पर

$ python -m timeit -s "d = {'f':1,'foo':2,'bar':3}" "d1 = d.copy()" 
1000000 loops, best of 3: 0.278 usec per loop 

बेंचमार्क:

$ python -m timeit -s "d = {'f':1,'foo':2,'bar':3}" "d1 = d.copy()" "for k in d1.keys():" " if k.startswith('f'):" " del d1[k]" 
100000 loops, best of 3: 1.95 usec per loop 

$ python -m timeit -s "d = {'f':1,'foo':2,'bar':3}" "d1 = d.copy()" "for k in d1.keys():" " if k.startswith('f'):" " d1.pop(k)" 
100000 loops, best of 3: 2.15 usec per loop 

नकल की लागत घटाने पर हम pop() के लिए 1.872 usec और del के लिए 1.672 मिलता है।

+0

आपको लगता है कि पॉप से ​​हटने से तेज़ी से पॉप? – HardQuestions

+0

@ माइक: यह दिखाने के लिए बेंचमार्क जोड़ा गया कि 'पॉप()' का उपयोग करने से आपका रास्ता थोड़ा तेज़ है जबकि अधिक पठनीय आईएमओ भी है। – bernie

+0

@ एडम बर्नीर सिर्फ इसलिए कि पॉप डेल नहीं करते समय एक मूल्य देता है। बड़े नियम या बड़े मूल्यों के साथ अंतर उल्लेखनीय होना चाहिए। – HardQuestions