2010-09-09 5 views
5

कैसे करता है:शब्दकोश कुंजी लुकअप का प्रदर्शन पाइथन में तुलना कैसे करता है?

dict = {} 
if key not in dict: 
dict[key] = foo 

की तुलना करने के लिए:

try: 
dict[key] 
except KeyError: 
dict[key] = foo 

यानी, वैसे में एक महत्वपूर्ण के स्वरूप को प्रभावी तेजी dict.keys() के माध्यम से रैखिक खोज की तुलना में, मुझे लगता है कि पहला रूप क्या करेंगे है?

+2

dict.setdefault विधि भी है: http://docs.python.org/release/2.6.6/library/stdtypes.html#mapping-types-dict – GWW

+10

पहला ** ** रैखिक नहीं है खोज के। जैसे लैरी वॉल ने इसे लिखा: "एक सहयोगी सरणी पर रैखिक स्कैन करना किसी को उज्ज्वल उजी के साथ मारने की कोशिश करना है।" 'dict .__ has__' लगभग' dict के पहले 2/3 के समान ही है।__getitem__' (एक हैश लुकअप)। – delnan

+3

यह एक महान उद्धरण है। – nmichaels

उत्तर

4

जवाब कितनी बार कुंजी dict में पहले से ही है पर निर्भर करता है (BTW, किसी को आप के लिए उल्लेख किया है कितना बुरा एक विचार यह एक चर के पीछे अंतर्निहित जैसे dict को छिपाने के लिए है?)

if key not in dct: 
dct[key] = foo 

यदि कुंजी शब्दकोश में है तो यह एक शब्दकोश लुकअप करता है। यदि कुंजी शब्दकोश में है तो यह दो बार शब्दकोश को देखती है।

try: 
dct[key] 
except KeyError: 
dct[key] = foo 

इस मामले में जहां कुंजी शब्दकोश में है के लिए थोड़ा तेजी से हो सकता है, लेकिन कोई अपवाद फेंकने काफी बड़ा भूमि के ऊपर है, इसलिए यह लगभग हमेशा सबसे अच्छा विकल्प नहीं है।

dct.setdefault(key, foo) 

यह एक थोड़ा मुश्किल है: यह हमेशा दो लुकअप शब्दकोश शामिल है: पहले एक dict कक्षा में setdefault विधि को मिल रहा है, दूसरी dct वस्तु में key देखने के लिए है। इसके अलावा यदि foo एक अभिव्यक्ति है तो इसका मूल्यांकन हर बार किया जाएगा जबकि पहले के विकल्प केवल तब मूल्यांकन करेंगे जब उन्हें करना होगा।

collections.defaultdict पर भी देखें। इस तरह की स्थितियों की एक बड़ी श्रेणी के लिए यह सबसे उपयुक्त समाधान है।

+1

'dict' का उपयोग करने पर अच्छा बिंदु मैंने उदाहरण टाइप करते समय परिवर्तनीय नाम बदल दिया और इसके बारे में नहीं सोचा। मुख्य कुंजी आमतौर पर ताना में नहीं होती है। –

+0

मैं संग्रह के साथ जा रहा हूँ .defaultdict, यह इंगित करने के लिए धन्यवाद। यह पाइथोनिक लगता है, और एक बाल dict.setdefault() –

+0

से अधिक तेजी से ब्रो – coleifer

-1

my_dict.get(key, foo) अगर my_dict में कुंजी नहीं है तो foo लौटाता है। डिफ़ॉल्ट मान कोई नहीं है, इसलिए my_dict.get(key) कोई नहीं लौटाएगा यदि कुंजी my_dict में नहीं है। यदि आप अपने शब्दकोश में कुंजी जोड़ना चाहते हैं तो आपके विकल्पों में से पहला बेहतर होगा। यहां गति के बारे में चिंता मत करो। यदि आपको लगता है कि आपके शब्दकोश में पॉपुलटिंग आपके प्रोग्राम में एक गर्म स्थान है, तो इसके बारे में सोचें। लेकिन यह नहीं है। सो डॉन'टी।

+0

+1 - बहुत पाइथोनिक। – duffymo

+1

यह मान निर्धारित नहीं करता है कि यह उसके कोड को देखकर सेट नहीं है, ऐसा प्रतीत होता है कि वह जांच रहा है कि कुंजी मौजूद है और अन्यथा इसे सेट कर रहा है। – GWW

+0

@GWW: सच है। आप 'dict [key] = dict.get (key, foo)' का उपयोग कर सकते हैं। – nmichaels

4

कोशिश करें: my_dict.setdefault(key, default)। हालांकि, यह अन्य विकल्पों की तुलना में थोड़ा धीमा है।

तो key शब्दकोश में है, अपने मूल्य वापसी। यदि नहीं, keydefault के मान के साथ डालें और default वापस करें। default किसी के लिए डिफ़ॉल्ट नहीं है।

#!/usr/bin/env python 

example_dict = dict(zip(range(10), range(10))) 

def kn(key, d): 
    if key not in d: 
     d[key] = 'foo' 

def te(key, d): 
    try: 
     d[key] 
    except KeyError: 
     d[key] = 'foo' 

def sd(key, d): 
    d.setdefault(key, 'foo') 

if __name__ == '__main__': 
    from timeit import Timer 

    t = Timer("kn(2, example_dict)", "from __main__ import kn, example_dict") 
    print t.timeit() 
    t = Timer("te(2, example_dict)", "from __main__ import te, example_dict") 
    print t.timeit() 
    t = Timer("sd(2, example_dict)", "from __main__ import sd, example_dict") 
    print t.timeit() 

    # kn: 0.249855041504 
    # te: 0.244259119034 
    # sd: 0.375113964081 
+0

यह काफी दिलचस्प है कि विधि में निर्मित पायथन इतना धीमा है। – GWW

+0

फंक्शन कॉल ओवरहेड, मुझे लगता है। – miku

+0

और यह दिलचस्प है कि 'psyco.full()' के साथ, सभी तीन प्रकारों में केवल 10% समय लगता है। – AndiDog

5

आप SetDefault विधि के लिए देख रहे:

>>> r = {} 
>>> r.setdefault('a', 'b') 
'b' 
>>> r 
{'a': 'b'} 
>>> r.setdefault('a', 'e') 
'b' 
>>> r 
{'a': 'b'} 
+0

+1;) – delnan

5

बस एक बिंदु स्पष्ट करने के लिए: if key not in d डी एस कुंजी के माध्यम से एक रेखीय खोज नहीं करता है। यह कुंजी को तुरंत ढूंढने के लिए dict की हैश तालिका का उपयोग करता है।

+0

बिल्कुल जो मैं ढूंढने की कोशिश कर रहा हूं - टा! –

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