सबसे पहले, key in d.keys()
आपको d
के लिए key in d
के समान मूल्य देने की गारंटी है।
और एक dict
पर in
आपरेशन, या dict_keys
वस्तु आप उस पर keys()
(3.x में) कॉल करने से वापस पाने, है नहीं हे (एन), यह हे है (1)।
कोई असली "अनुकूलन" नहीं चल रहा है; यह हैश हैश का उपयोग करना हैश तालिका पर __contains__
को लागू करने का स्पष्ट तरीका है, क्योंकि यह __getitem__
को लागू करने का स्पष्ट तरीका है।
आप पूछ सकते हैं कि यह कहां गारंटी है।
अच्छा, यह नहीं है। Mapping Typesdict
को मूल रूप से collections.abc.Mapping
के हैश तालिका कार्यान्वयन के रूप में परिभाषित करता है। किसी को मैपिंग के हैश टेबल कार्यान्वयन को बनाने से रोकना कुछ भी नहीं है, लेकिन फिर भी ओ (एन) खोज प्रदान करता है। लेकिन यह इतना बुरा कार्यान्वयन करने के लिए अतिरिक्त काम होगा, तो वे क्यों होंगे?
तुम सच में अपने आप को यह साबित करने की जरूरत है, तो आप हर कार्यान्वयन आप ध्यान परीक्षण कर सकते हैं (एक प्रोफाइलर साथ, या एक कस्टम __hash__
और __eq__
कि कॉल लॉग के साथ कुछ प्रकार का उपयोग करके, या ...), या स्रोत पढ़ ।
2.x में, आप नहीं keys
कॉल करने के लिए, चाहते हैं, क्योंकि है कि एक KeysView
के बजाय चाबियों का एक list
उत्पन्न करता है,। आप iterkeys
का उपयोग कर सकते हैं, लेकिन यह एक इटरेटर या कुछ और उत्पन्न कर सकता है जो ओ (1) नहीं है। तो, बस एक अनुक्रम के रूप में खुद को प्रयोग करें।
यहां तक कि 3.x में, आप keys
पर कॉल नहीं करना चाहते हैं, क्योंकि इसकी कोई आवश्यकता नहीं है। dict
को इटरेट करना, इसकी __contains__
जांचना, और सामान्य रूप से इसे अनुक्रम की तरह व्यवहार करना हमेशा अपनी चाबियों को एक ही चीज़ करने के बराबर है, तो परेशान क्यों करें?(और निश्चित रूप से छोटे KeyView
का निर्माण, और इसके माध्यम से पहुंचने के लिए, आपके चलने वाले समय में कुछ नैनोसेकंड और आपके प्रोग्राम में कुछ कीस्ट्रोक जोड़ने जा रहे हैं।)
(यह स्पष्ट नहीं है कि अनुक्रम संचालन का उपयोग करना समकक्ष है d.keys()
/d.iterkeys()
और d
2.x में प्रदर्शन प्रदर्शन मुद्दों के अलावा, प्रत्येक सीपीथन, ज्योथन, आयरनपीथन और पीपीपी कार्यान्वयन के बराबर हैं, लेकिन ऐसा लगता है कि यह कहीं भी 3.x में नहीं है । और यह कोई प्रभाव नहीं पड़ेगा, बस key in d
का उपयोग)
हम एक कर रहे हैं। टी, ध्यान दें कि यह:
if(dict[key] != None):
... काम नहीं करेगा। यदि key
dict
में नहीं है, तो यह KeyError
बढ़ाएगा, None
वापस नहीं करेगा।
इसके अलावा, आपको ==
या !=
के साथ None
कभी भी जांचना नहीं चाहिए; हमेशा is
का उपयोग करें।
आप इसे try
-या अधिक आसानी से कर सकते हैं, if dict.get(key, None) is not None
करें। लेकिन फिर, ऐसा करने का कोई कारण नहीं है। साथ ही, यह उन मामलों को संभाल नहीं पाएगा जहां None
एक पूरी तरह से वैध आइटम है। यदि ऐसा है, तो आपको sentinel = object(); if dict.get(key, sentinel) is not sentinel:
जैसे कुछ करने की आवश्यकता है।
तो, सही बात लिखने के लिए:
if key in d:
आम तौर पर, यह सच नहीं है:
I know the "in" keyword is generally O(n) (as this just translates to python iterating over an entire list and comparing each element
in
ऑपरेटर, अधिकांश अन्य ऑपरेटरों की तरह, __contains__
विधि (या सी/जावा/.NET/RPython अंतर्निहित के बराबर) के लिए सिर्फ एक कॉल है। list
सूची को पुन: स्थापित करके और प्रत्येक तत्व की तुलना करके इसे लागू करता है; dict
मूल्य को हश करके और हैश को देखकर इसे लागू करता है; blist.blist
बी + ट्री चलकर इसे लागू करता है; आदि। तो, यह ओ (एन), ओ (1), ओ (लॉग एन) हो सकता है, या कुछ पूरी तरह से अलग हो सकता है।
मैं कहता हूं कि सबसे आसान क्या है, और बाद में प्रोफ़ाइल। – jh314
वास्तव में, नीचे कोड काम नहीं करेगा। आपको कोशिश करने के लिए कुछ करना है: dict [key]; KeyError को छोड़कर: पास; अन्य: # ... कोड ... '। –
@TravisGD यह एक अच्छा मुद्दा है, मैं उस – tknickman