2008-12-04 10 views
12

dict विधियों dict.keys(), dict.items() और dict.values ​​() सूचियों के बजाय लौटते हैं। http://docs.python.org/dev/3.0/whatsnew//3.0.htmlपायथन 3.0 - dict विधियों के दृश्य वापस - क्यों?

सबसे पहले एक पुनरावर्तक से एक दृश्य अलग कैसे है? दूसरा, इस परिवर्तन का क्या फायदा है? क्या यह सिर्फ प्रदर्शन कारणों से है?

यह मेरे लिए सहज नहीं लगता है, यानी, मैं चीज़ की एक सूची मांग रहा हूं (मुझे अपनी सभी चाबियाँ दें) और मुझे कुछ और वापस मिल रहा है। क्या यह लोगों को भ्रमित करेगा?

+0

इस stackoverflow पर एक महान जवाब है: http://stackoverflow.com/questions/8957750/what-are-python-dictionary-view-objects – Exthen

+0

लगता यूआरएल मर चुका है की तरह। – Borealis

उत्तर

13

आप प्रभावी रूप से एक सूची प्राप्त कर रहे हैं। यह सिर्फ आंतरिक सूची की प्रति नहीं है, लेकिन ऐसा कुछ है जो कार्य करता है जैसे कि यह एक सूची है लेकिन केवल आंतरिक स्थिति का प्रतिनिधित्व करता है।

इसी तरह जावा में लागू किया गया है (और शायद कई अन्य भाषाओं/वातावरण भी)।

मुख्य कारण यह है कि कई उपयोग मामलों के लिए पूरी तरह से अलग सूची लौटने के लिए अनावश्यक और अपर्याप्त है। इसे पूरी सामग्री की प्रतिलिपि बनाने की आवश्यकता होगी (जो बहुत अधिक हो सकता है)।

यदि आप बस चाबियों पर फिर से चलना चाहते हैं तो एक नई सूची बनाना जरूरी नहीं है। और यदि आपको वास्तव में इसे एक अलग सूची (एक प्रति के रूप में) की आवश्यकता है तो आप आसानी से उस सूची को दृश्य से बना सकते हैं।

6

जोआचिम सॉर का जवाब बहुत अच्छी तरह से बताता है कि list वापस नहीं किया गया है। लेकिन यह सवाल छोड़ देता है कि ये फ़ंक्शन इटेटरेटर्स क्यों नहीं लौटाएंगे, जैसे कि iteritems इत्यादि पायथन 2 में किया गया था।

एक पुनरावर्तक एक कंटेनर से अधिक प्रतिबंधित है। उदाहरण के लिए, एक पुनरावर्तक एक से अधिक पास की अनुमति नहीं देता है; यदि आप दूसरे पास का प्रयास करते हैं, तो आप पाएंगे कि यह खाली है। इसलिए, elem in cont जैसे ऑपरेशन कंटेनर द्वारा समर्थित हैं, लेकिन इसे इटरेटर्स द्वारा समर्थित नहीं किया जा सकता है: एक बार जब आप यह जांच लें कि कोई तत्व इटरेटर में "अंदर" है, तो इटेटरेटर नष्ट हो जाता है!

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

view ऑब्जेक्ट दोनों दुनिया में सर्वश्रेष्ठ है: यह एक कंटेनर के रूप में व्यवहार करता है, और फिर भी शब्दकोश की एक प्रति नहीं बनाता है! वास्तव में, यह एक प्रकार का वर्चुअल रीड-ओनली कंटेनर है जो अंतर्निहित शब्दकोश से जुड़कर काम करता है। मुझे नहीं पता कि यह मानक पायथन में कहीं और देखा गया है या नहीं।

संपादित करें:

@AntonyHatchkins: कारण यह एक जनरेटर समारोह वापस नहीं करता है कि यह एक तेजी से in ऑपरेशन के लिए अनुमति नहीं होगी है। हां, in जनरेटर फ़ंक्शंस के लिए काम करता है (जब आप उन्हें कॉल करते हैं)। अर्थात, आप ऐसा कर सकते हैं:

def f(): 
    for i in range(10): 
    yield i 

5 in f() # True 

लेकिन in की परिभाषा के अनुसार, अगर सही पक्ष एक जनरेटर है, अजगर सभी n जनरेटर के आइटम के माध्यम से जाना होगा - O(n) समय जटिलता के लिए अग्रणी। इसके बारे में आप कुछ भी नहीं कर सकते क्योंकि यह एक मनमाने ढंग से जनरेटर का एकमात्र सार्थक व्यवहार है।

दूसरी ओर, शब्दकोश दृश्य के मामले में, आप in को किसी भी तरह से लागू कर सकते हैं, क्योंकि आप अपने द्वारा प्रबंधित डेटा के बारे में अधिक जानते हैं। और वास्तव में in को हैश तालिका का उपयोग करके O(1) जटिलता के साथ कार्यान्वित किया गया है। आप

>>> d = dict(zip(range(50000000), range(50000000))) 
>>> 49999999 in d 
True 
>>> 49999999 in iter(d) # kinda how generator function would work 
True 
>>> 

चल रहा है और देख कितनी तेजी से पहले in दूसरा in की तुलना में है द्वारा यह जांच कर सकते हैं।

+0

फिर एक और सवाल है कि जेनरेटर फ़ंक्शन क्यों नहीं लौटाएंगे। वे बहु-पास इकाइयां हैं (इस प्रकार 'elem cont cont संचालन में भी सहायता करते हैं) और अधिक मेमोरी नहीं लेते हैं। –

+0

@ एंटनी हैचकिन्स ने – max

+0

कारण बताए जाने के उत्तर को संपादित किया धन्यवाद, मैंने तब से इसे स्वयं सीखा है, लेकिन यह अन्य लोगों के लिए भी उपयोगी हो सकता है। –

0

जैसा कि पहले से संबंधित प्रश्न में बताया गया था, देखें len() विधि है, जिसमें इटरेटर की कमी है (अभी तक सूची में है)।

सूची के बजाय दृश्य लौटने का एक अन्य लाभ यह है कि कम से कम कुंजी के लिए यह सूची (या पुनरावर्तक) के लिए ओ (एन) के बजाय ओ (1) संचालन में एक अनुकूलित सदस्यता परीक्षण है।

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