2012-04-17 7 views
25

पायथन 2.7 में, शब्दकोशों में iterkeys विधि और viewkeys विधि (और मूल्यों और वस्तुओं के लिए समान जोड़े) दोनों हैं, जो दो अलग-अलग तरीकों को शब्दकोश के कुंजी पर आलसी ढंग से फिर से भरने के लिए देते हैं। viewkeys विधि iterkeys की प्रमुख विशेषता प्रदान करता है, प्रभावी रूप से d.iterkeys() के बराबर है। इसके अतिरिक्त, viewkeys लौटाई गई वस्तुओं में सुविधाजनक सेट-जैसी सुविधाएं हैं। इस प्रकार viewkeysiterkeys से अधिक पक्षपात करने के मजबूत कारण हैं।एक पायथन शब्दकोश के लिए, क्या itkeykeys दृश्यियों पर कोई लाभ प्रदान करता है?

दूसरी दिशा के बारे में क्या? पायथन के पुराने संस्करणों के साथ संगतता के अलावा, क्या ऐसे कोई तरीके हैं जिनमें iterkeysviewkeys के लिए बेहतर होगा? viewkeys का उपयोग करके हमेशा कुछ खो जाएंगे?

+2

* "पायथन के पिछले संस्करणों के साथ संगतता के अलावा" * - बात यह है कि आप ऐसा कुछ नहीं कर सकते जिसे आप शायद ही अप्रासंगिक कह सकें। अन्यथा, हर कोई Python3.2 का उपयोग कर रहा है पहले से ही – vartec

+4

@vartec यह अप्रासंगिक नहीं है, लेकिन यह स्पष्ट है। –

+0

लेकिन फिर फिर से, 'iterkeys()' के अलावा 'viewkeys()' पर लाभ नहीं है। – vartec

उत्तर

8

नहीं, iterkeysviewkeys से अधिक लाभ नहीं है, वैसे ही keys पर इनमें से कोई भी लाभ नहीं है। iterkeys केवल पीछे संगतता के लिए है। दरअसल, पायथन 3, viewkeys में एकमात्र व्यवहार है जो अभी भी मौजूद है, और इसका नाम बदलकर keys कर दिया गया है - viewkeys विधि वास्तव में पायथन 3 व्यवहार का बैकपोर्ट है।

+4

यह किसी भी अंतर को – SystemParadox

+5

@ सिस्टम पाराडॉक्स को स्पष्ट रूप से नहीं बताता है कि सवाल स्पष्ट रूप से नहीं पूछता कि अंतर क्या हैं - ओपी विशेष रूप से पूछता है कि क्या है 'iter *' 'view *' से अधिक का उपयोग करने के लिए कोई लाभ, और * पहले से ही अन्य दिशाओं में फायदे सूचीबद्ध करता है। – lvc

21

शब्दकोश के रूप में एक शब्दकोश देखने के लिए अद्यतन, जबकि एक iterator यह आवश्यक नहीं है।

इसका मतलब है कि यदि आप दृश्य के साथ काम करते हैं, तो शब्दकोश को बदलें, फिर दृश्य के साथ फिर से काम करें, दृश्य शब्दकोश के नए राज्य को प्रतिबिंबित करने के लिए बदल जाएगा।

वे शब्दकोश की प्रविष्टियों पर एक गतिशील दृश्य प्रदान करते हैं, जिसका अर्थ है कि जब शब्दकोश बदलता है, तो दृश्य इन परिवर्तनों को दर्शाता है। Source

उदाहरण:

>>> test = {1: 2, 3: 4} 
>>> a = test.iterkeys() 
>>> b = test.viewkeys() 
>>> del test[1] 
>>> test[5] = 6 
>>> list(a) 
[3, 5] 
>>> b 
dict_keys([3, 5]) 

परिवर्तन आकार करने के लिए बनाया जाता है, तो एक अपवाद फेंक दिया जाएगा:

>>> test = {1: 2, 3: 4} 
>>> a = test.iterkeys() 
>>> b = test.viewkeys() 
>>> test[5] = 6 
>>> list(a) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
RuntimeError: dictionary changed size during iteration 
>>> b 
dict_keys([1, 3, 5]) 

यह भी केवल एक बार एक keyiterator से अधिक पुनरावृति कर सकते हैं ध्यान देने योग्य है :

>>> test = {1: 2, 3: 4} 
>>> a = test.iterkeys() 
>>> list(a) 
[1, 3] 
>>> list(a) 
[] 
>>> b = test.viewkeys() 
>>> b 
dict_keys([1, 3]) 
>>> b 
dict_keys([1, 3]) 
+2

यह सब सच है, लेकिन वास्तव में सवाल को संबोधित नहीं करता है - ओपी जानता है कि 'व्यूकी' क्या करती है, और विशेष रूप से पूछ रही है कि 'iterkeys 'का नाटक करने के कोई नुकसान मौजूद नहीं हैं या नहीं। – lvc

+2

@lvc यह अंतर को समझाता है, जिसे 'iterkeys()' 'के सकारात्मक माना जा सकता है - उदाहरण के लिए, यदि आप' iterkeys() '' का उपयोग करके अद्यतन होने की संभावना नहीं चाहते हैं, तो यह अधिक उपयुक्त हो सकता है (हालांकि वही कार्यक्षमता '' viewkeys() '' के साथ बनाई जा सकती है)। मैं यह नहीं कह रहा कि यह एक मजबूत कारण है, लेकिन यह केवल एकमात्र है। –

+0

@ लार्समैन कोई तर्क दे सकता है कि यह अद्यतन संस्करण पर चुपचाप काम करने से बेहतर था जहां आप इसे नहीं चाहते थे, लेकिन मैं मानता हूं कि यह एक खिंचाव है। हां, संक्षिप्त जवाब यह है कि 'iterkeys()' 'का उपयोग करने का कोई कारण नहीं है, यही कारण है कि यह Python3 में चला गया है।हालांकि, मैंने सोचा कि मैं आशा में मतभेदों को समझाऊंगा कि यह भेद स्पष्ट हो गया है। –

7

नाम के रूप में (और documentation) से संकेत मिलता है, viewkeys(), viewvalues() और viewitems() तरीकों शब्दकोश जिसका अर्थ है कि यदि शब्दकोश बदलती है, जिससे दृश्य करता है में मौजूदा तत्वों के एक दृश्य वापसी; विचार lazy हैं। सामान्य मामले में कुंजी विचार सेट-जैसे हैं, और आइटम विचार केवल तभी सेट किए गए हैं जब मान हैंशबल हैं।

मानक विधियों keys(), values() और items() का उपयोग करने के लिए कौन से मामले बेहतर होंगे? आपने एक बहुत ही महत्वपूर्ण उल्लेख किया है: पिछड़ा संगतता। साथ ही, जब आपको मूल कुंजी को संशोधित किए बिना लौटाई गई सूची को संशोधित करने की आवश्यकता होती है और जब आपको किसी स्नैपशॉट की आवश्यकता होती है, तो आपको सभी कुंजियों, मानों या वस्तुओं (एक सेट-जैसी नहीं, एक पुनरावर्तक नहीं) की एक साधारण सूची की आवश्यकता होती है। शब्दकोश में चाबियाँ, मान या आइटम समय पर एक पल में, शब्दकोश पर किसी भी पूर्ववर्ती संशोधन से स्वतंत्र।

और iterkeys(), itervalues() और iteritems() के बारे में क्या? वे एक उपयुक्त विकल्प हैं जब आपको एक शॉट, स्थिर-स्थान, आलसी इटेटरेटर स्नैपशॉट की एक शब्दकोश की सामग्री की आवश्यकता होती है जो आपको बताएगी कि शब्दकोश को फिर से बदलते समय संशोधित किया गया था (RuntimeError के माध्यम से), वे पीछे की ओर भी बहुत महत्वपूर्ण हैं संगतता।

+1

मुझे डर नहीं है - ['(शब्दकोश दृश्य) आलसी अनुक्रम हैं'] (http://docs.python.org/glossary.html) –

+0

@ लैटवेयर धन्यवाद, इसे ठीक करें। –

+1

मामूली स्पष्टीकरण: आइटम दृश्य केवल तभी सेट किए गए हैं जब मान हैंशबल हैं। –

12

कार्यक्षमता के अनुसार, जैसा कि आपने देखा है, विचार बेहतर हैं। संगतता के अनुसार, वे बदतर हैं।

कुछ प्रदर्शन मेट्रिक्स, एक 64-बिट Ubuntu मशीन पर अजगर 2.7.2 से लिया:

>>> from timeit import timeit 

एक खाली शब्दकोश से निपटना:

>>> emptydict = {} 
>>> timeit(lambda: emptydict.viewkeys()) 
0.24384498596191406 
>>> timeit(lambda: list(emptydict.viewkeys())) 
0.4636681079864502 
>>> timeit(lambda: emptydict.iterkeys()) 
0.23939013481140137 
>>> timeit(lambda: list(emptydict.iterkeys())) 
1.0098130702972412 

दृश्य का निर्माण थोड़ा और अधिक महंगा है, लेकिन दृश्य का उपभोग करने वाले इटरेटर से काफी तेज़ है (थोड़ा तेज़ से थोड़ा अधिक)।

एक हजार तत्व शब्दकोश से निपटना:

>>> fulldict = {i: i for i in xrange(1000)} 
>>> timeit(lambda: fulldict.viewkeys()) 
0.24295306205749512 
>>> timeit(lambda: list(fulldict.viewkeys())) 
13.447425842285156 
>>> timeit(lambda: fulldict.iterkeys()) 
0.23759889602661133 
>>> timeit(lambda: list(fulldict.iterkeys())) 
15.45390510559082 

एक ही परिणाम है, हालांकि कम चिह्नित; दृश्य का निर्माण बहुत महंगा है, लेकिन इसका उपभोग करना काफी निश्चित रूप से तेज़ है (15% तेज)।

>>> timeit(lambda: emptydict.keys()) 
0.2385849952697754 
>>> timeit(lambda: fulldict.keys()) 
7.842105150222778 

सारांश::

list(dict.viewkeys()) और list(dict.iterkeys()) साथ निष्पक्ष तुलना के लिए, dict.keys() distinctlyfaster है यह एक व्यापार बंद है, बेहतर कार्यक्षमता (जिसे आप शायद ही कभी उपयोग करेंगे) और प्रदर्शन (जो केवल बहुत आपको — पर चिंता करने के लिए पर्याप्त रूप से महत्वपूर्ण होगा यदि आप इस तरह के प्रदर्शन मामलों की देखभाल कर रहे हैं, तो शायद आप पहले से ही numpy के साथ काम करने की आवश्यकता के क्षेत्र में हैं/scipy) बनाम बेहतर संगतता और मांसपेशी स्मृति उपयोग बनाम।

व्यक्तिगत रूप से, जब तक कि पहले से ही 2.7-केवल कार्यक्षमता के आधार पर या जब तक कि मैं रनटाइम पर्यावरण को पूरी तरह से नियंत्रित नहीं कर रहा हूं, मैं पाइथन 2 कोड में शब्दकोश दृश्यों से बचूंगा। यहां तक ​​कि इन मामलों में, मेरी उंगलियां अभी भी view के बजाय iter टाइप करना चाहती हैं, इसलिए मैं इसे छोड़ देता हूं!

+0

हम में से कुछ वक्र से आगे रहते हैं, मुझे पता है कि मैं सिर्फ पायथन 3.x का उपयोग करने के कारण '' आइटम() '' और दोस्तों के लिए डिफ़ॉल्ट हूं। जब मैं पाइथन 2.x पर वापस जाता हूं तो मुझे सावधान रहना होगा। ईमानदार होने के लिए, जबकि 3.x समर्थन मिश्रित बैग है, 2.7.3 समर्थन इस बिंदु पर काफी सार्वभौमिक है, अजीब को दें या ले लो। –

+0

@ लैटवेयर: मुझे यह समस्या नहीं मिली है क्योंकि मैंने अभी तक किसी भी प्रोजेक्ट के लिए पायथन 3 का उपयोग नहीं किया है (अभी भी पाइथन 2-केवल चीजों के आधार पर, जैसे Django)। –

+0

हम सभी जो सामान हम उपयोग करते हैं उससे बाध्य हैं। मैं Django सिर पूर्ण 3.x संगतता के करीब हो रही है हालांकि। ओह, और मैं कहने के लिए भूल गया, पूरी तरह से गति विश्लेषण के लिए +1। –

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

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