Python2 में तानाशाही () और तानाशाही () के बीच क्या अंतर है?


705

क्या dict.items()और के बीच कोई लागू अंतर हैं dict.iteritems()?

से अजगर डॉक्स :

dict.items(): शब्दकोश की (की, मूल्य) जोड़े की सूची की एक प्रति लौटाएं ।

dict.iteritems(): शब्दकोश (कुंजी, मूल्य) जोड़े पर एक पुनरावृत्ति लौटें ।

यदि मैं नीचे दिए गए कोड को चलाता हूं, तो प्रत्येक उसी वस्तु का संदर्भ देता है। क्या कोई सूक्ष्म अंतर है जो मुझे याद आ रहा है?

#!/usr/bin/python

d={1:'one',2:'two',3:'three'}
print 'd.items():'
for k,v in d.items():
   if d[k] is v: print '\tthey are the same object' 
   else: print '\tthey are different'

print 'd.iteritems():'   
for k,v in d.iteritems():
   if d[k] is v: print '\tthey are the same object' 
   else: print '\tthey are different'   

आउटपुट:

d.items():
    they are the same object
    they are the same object
    they are the same object
d.iteritems():
    they are the same object
    they are the same object
    they are the same object

41
यह मूल रूप से एक अंतर है कि उनकी गणना कैसे की जाती है। items()आइटम को एक ही बार में बनाता है और एक सूची देता है। iteritems()एक जनरेटर लौटाता है - एक जनरेटर एक वस्तु है जो हर बार उस next()पर कॉल किए जाने वाले समय में एक आइटम को "बनाता है" ।
जोएल कॉर्नेट

9
आपके विशेष मामले में, d[k] is vहमेशा सही वापस आएगा क्योंकि अजगर -5 और 256 के बीच सभी पूर्णांकों के लिए पूर्णांक ऑब्जेक्ट की एक सरणी रखता है: docs.python.org/2/c-api/int.html जब आप उस सीमा में एक इंट बनाते हैं तो आप वास्तव में सिर्फ मौजूदा वस्तु का संदर्भ मिलता है: >> a = 2; b = 2 >> a is b Trueलेकिन,>> a = 1234567890; b = 1234567890 >> a is b False
t_tia

3
@the_wolf मुझे लगता है कि डॉक के अजगर संस्करण को आप प्रश्न में संदर्भित करना बेहतर होगा।
लोरेंजो बेली

2
क्या iteritems()करने के लिए परिवर्तन iter()अजगर 3 में? ऊपर दिए गए दस्तावेज़ीकरण लिंक इस उत्तर के साथ मेल नहीं खाते।
गेब्रियल स्टेपल्स

3
बिल्कुल नहीं, @GabrielStaples। iteritems () शब्दकोशों 3 पायथन से हटा दिया गया है, और कोई प्रतिस्थापन नहीं है। हालांकि, एक ही प्रभाव के लिए, आप iter () का उपयोग करते हैं। जैसे iter (dict.items ())। पेप 469 देखें: python.org/dev/peps/pep-0469
Zim

जवाबों:


864

यह एक विकास का हिस्सा है।

मूल रूप से, पायथन items()ने टुपल्स की एक वास्तविक सूची बनाई और उसे वापस कर दिया। यह संभावित रूप से बहुत सारी अतिरिक्त मेमोरी ले सकता है।

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

पायथन 3 के परिवर्तनों में से एक यह है कि items()अब पुनरावृत्तियों को लौटाएं, और एक सूची कभी भी पूरी तरह से निर्मित नहीं होती है। iteritems()विधि को भी चला गया है के बाद से, items()पायथन में 3 काम करता है की तरह viewitems()अजगर 2.7 में।


159
ध्यान दें कि आपने विकास में एक कदम याद किया है: Py3 व्यवहार वैसा नहीं है iteritems()। यह वास्तव में एक फुल सीक्वेंस-प्रोटोकॉल ऑब्जेक्ट बनाता है जो डिक्टेंड में बदलावों को दर्शाता है (और एक निरर्थक सूची के बजाय केवल स्वयं द्वारा समर्थित है) - इसे 2.7 के रूप में बैकपोर्ट किया गया है viewitems()
LVC

3
मैं इसके बारे में अधिक विस्तार से जानना चाहता हूं, लेकिन मेरा गूगल-फू मुझे विफल कर रहा है। क्या कोई मुझे प्रलेखन, लेख या स्रोत की ओर इशारा कर सकता है जो मुझे इसे समझने में बेहतर मदद करेगा? @lvc?
स्टू

10
@ परिवर्तन PEP 3106 में वर्णित है और अजगर 3.0
मैकडोनाल्ड-जेन्सेन

1
इस प्राचीन प्रश्न के बारे में विस्तार से खेद है, लेकिन क्या मैं सही ढंग से समझता हूं कि पायथन 2.x में iteritems()हमेशा बेहतर होताitems() है?
RubenGeert

2
@RubenGeert अधिकांश समय, इससे कोई फर्क नहीं पड़ता। वास्तव में बड़े dicts के लिए यह बेहतर हो सकता है।
कीथ

95

dict.items()2-टुपल्स ( [(key, value), (key, value), ...]) की सूची देता है , जबकि dict.iteritems()एक जनरेटर है जो 2-टुपल्स देता है। पूर्व में शुरू में अधिक स्थान और समय लगता है, लेकिन प्रत्येक तत्व तक पहुंच तेज है, जबकि दूसरा शुरू में कम स्थान और समय लेता है, लेकिन प्रत्येक तत्व को उत्पन्न करने में थोड़ा अधिक समय लगता है।


9
आप उनसे अलग होने की उम्मीद क्यों करेंगे?
इग्नासियो वाज़केज़-अब्राम्स

3
डॉक्स में "कॉपी" का मतलब यह नहीं है कि तत्व कॉपी किए गए हैं (यदि आप चाहते हैं कि, उपयोग करें copy.deepcopy)। इसका मतलब है कि यह शब्दकोश आइटमों की एक प्रति है: यदि आप करते हैं items = dct.items()और फिर dctकुंजी जोड़कर / हटाकर संशोधित करते हैं या dct[k] = other_v, itemsवही रहेंगे।
डगल

4
जब तक स्पष्ट रूप से इस तरह से प्रलेखित नहीं किया जाता है, पायथन में कुछ भी कभी भी एक गहरी प्रतिलिपि नहीं है।
कार्ल Knechtel

1
@ इग्नासियोवेज़्क्यूज़-अब्राम्स - "अधिक स्थान और समय" के बारे में: वे किस आकार के शब्दकोश में बात करना शुरू करते हैं। कहो कि मैं एक "बड़ा" शब्दकोश {1:'one', 2:'two', ... }हूं, जिस पर मैं एक वेबसर्वर पर चलना चाहता हूं और परिणाम प्रस्तुत करना चाहता हूं। .items()बनाम .iteritems()पायथन 2.7 के लिए मुझे किस पैमाने पर चिंता करना शुरू करना चाहिए ?
उपयोगकर्ता

1
@ बफ़र: वास्तव में निश्चित नहीं। मेरा अनुमान 15-20 आइटम होगा, लेकिन मैंने इसका परीक्षण नहीं किया है।
इग्नासियो वाज़क्वेज़-अब्राम्स

64

Py2.x में

आदेश dict.items(), dict.keys()और जोड़ी, चाबियाँ और मूल्यों की शब्दकोश की सूची की dict.values()एक प्रति लौटाते हैं। यदि कॉपी की गई सूची बहुत बड़ी है तो यह बहुत सारी मेमोरी ले सकता है।(k, v)

आज्ञाओं dict.iteritems(), dict.iterkeys()और शब्दकोश की जोड़ी, कुंजियों और मूल्यों पर dict.itervalues()एक पुनरावृत्त लौटें (k, v)

कमांड dict.viewitems(), dict.viewkeys()और दृश्य ऑब्जेक्ट्स कोdict.viewvalues() लौटाते हैं , जो शब्दकोश के परिवर्तनों को प्रतिबिंबित कर सकते हैं। (यानी यदि आप delएक आइटम बनाते हैं या (k,v)शब्दकोश में एक जोड़ी जोड़ते हैं , तो दृश्य ऑब्जेक्ट स्वचालित रूप से एक ही समय में बदल सकता है ।)

$ python2.7

>>> d = {'one':1, 'two':2}
>>> type(d.items())
<type 'list'>
>>> type(d.keys())
<type 'list'>
>>> 
>>> 
>>> type(d.iteritems())
<type 'dictionary-itemiterator'>
>>> type(d.iterkeys())
<type 'dictionary-keyiterator'>
>>> 
>>> 
>>> type(d.viewitems())
<type 'dict_items'>
>>> type(d.viewkeys())
<type 'dict_keys'>

जबकि Py3.x में

Py3.x में, चीज़ें वहाँ केवल हैं के बाद से, और अधिक साफ कर रहे हैं dict.items(), dict.keys()और dict.values()उपलब्ध है, जो लौट दृश्य वस्तुओं बस के रूप में dict.viewitems()में Py2.x किया था।

परंतु

बस के रूप में @lvc बताया गया है, दृश्य वस्तु के समान नहीं है इटरेटर इसलिए यदि आप एक वापसी करना चाहते हैं, इटरेटर Py3.x में, आप इस्तेमाल कर सकते हैं iter(dictview):

$ python3.3

>>> d = {'one':'1', 'two':'2'}
>>> type(d.items())
<class 'dict_items'>
>>>
>>> type(d.keys())
<class 'dict_keys'>
>>>
>>>
>>> ii = iter(d.items())
>>> type(ii)
<class 'dict_itemiterator'>
>>>
>>> ik = iter(d.keys())
>>> type(ik)
<class 'dict_keyiterator'>

34

आपने पूछा: 'क्या तानाशाही () और तानाशाही के बीच कोई अंतर है।

यह मदद कर सकता है (पायथन 2.x के लिए):

>>> d={1:'one',2:'two',3:'three'}
>>> type(d.items())
<type 'list'>
>>> type(d.iteritems())
<type 'dictionary-itemiterator'>

आप देख सकते हैं कि d.items()कुंजी, मूल्य जोड़े के tuples की एक सूची d.iteritems()देता है और एक शब्दकोश-आयताकार लौटाता है।

एक सूची के रूप में, d.items () टुकड़ा-सक्षम है:

>>> l1=d.items()[0]
>>> l1
(1, 'one')   # an unordered value!

लेकिन एक __iter__विधि नहीं होगी :

>>> next(d.items())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list object is not an iterator

पुनरावर्तक के रूप में, d.iteritems () है नहीं टुकड़ा करने योग्य:

>>> i1=d.iteritems()[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'dictionary-itemiterator' object is not subscriptable

लेकिन है __iter__:

>>> next(d.iteritems())
(1, 'one')               # an unordered value!

तो आइटम खुद ही समान हैं - वस्तुओं को वितरित करने वाले कंटेनर अलग हैं। एक एक सूची है, दूसरा एक पुनरावृत्ति (पायथन संस्करण पर निर्भर करता है ...)

तो श्रुतलेखों के बीच लागू अंतर () और तानाशाही () एक सूची और एक पुनरावृत्ति के बीच लागू अंतर के समान हैं।


15

dict.items()टुपल्स की वापसी सूची, और dict.iteritems()शब्दकोश में टपल की पुनरावृति वस्तु के रूप में (key,value)। टुपल्स समान हैं, लेकिन कंटेनर अलग है।

dict.items()मूल रूप से सभी शब्दकोश को सूची में कॉपी करता है। का निष्पादन समय की तुलना करने के लिए निम्न कोड का उपयोग करके देखें dict.items()और dict.iteritems()। आपको फर्क दिखाई देगा।

import timeit

d = {i:i*2 for i in xrange(10000000)}  
start = timeit.default_timer() #more memory intensive
for key,value in d.items():
    tmp = key + value #do something like print
t1 = timeit.default_timer() - start

start = timeit.default_timer()
for key,value in d.iteritems(): #less memory intensive
    tmp = key + value
t2 = timeit.default_timer() - start

मेरी मशीन में आउटपुट:

Time with d.items(): 9.04773592949
Time with d.iteritems(): 2.17707300186

यह स्पष्ट रूप से दर्शाता है कि dictionary.iteritems()बहुत अधिक कुशल है।


4

यदि आपके पास है

dict = {key1:value1, key2:value2, key3:value3,...}

में अजगर 2 , dict.items()प्रतियां प्रत्येक tuples और रिटर्न शब्दकोश यानी में tuples की सूची [(key1,value1), (key2,value2), ...]। निहितार्थ यह है कि पूरे शब्दकोश को नई सूची में शामिल किया गया है जिसमें टुपल्स शामिल हैं

dict = {i: i * 2 for i in xrange(10000000)}  
# Slow and memory hungry.
for key, value in dict.items():
    print(key,":",value)

dict.iteritems()शब्दकोश आइटम पुनरावृति देता है। लौटाई गई वस्तु का मूल्य भी वही है (key1,value1), (key2,value2), ..., लेकिन यह कोई सूची नहीं है। यह केवल शब्द आइटम पुनरावृत्त वस्तु है। इसका मतलब है कि मेमोरी का कम उपयोग (50% कम)।

  • परिवर्तनशील स्नैपशॉट के रूप में सूची: d.items() -> list(d.items())
  • Iterator वस्तुएँ: d.iteritems() -> iter(d.items())

टुपल्स वही हैं। आप प्रत्येक में tuples की तुलना करते हैं ताकि आप समान हों।

dict = {i: i * 2 for i in xrange(10000000)}  
# More memory efficient.
for key, value in dict.iteritems():
    print(key,":",value)

में अजगर 3 , dict.items()रिटर्न वस्तु iterator। dict.iteritems () को हटा दिया जाता है ताकि कोई और समस्या न हो।


4

dict.iteritemsPython3.x में चला गया है, इसलिए iter(dict.items())समान आउटपुट और मेमोरी अलोकेशन प्राप्त करने के लिए उपयोग करें


1

यदि आप एक ऐसे शब्दकोश के आइटम जोड़े को पुनरावृत्त करना चाहते हैं जो पायथन 2 और 3 दोनों के साथ काम करता है, तो कुछ इस तरह से प्रयास करें:

DICT_ITER_ITEMS = (lambda d: d.iteritems()) if hasattr(dict, 'iteritems') else (lambda d: iter(d.items()))

इसे इस तरह उपयोग करें:

for key, value in DICT_ITER_ITEMS(myDict):
    # Do something with 'key' and/or 'value'.

0

dict.iteritems(): आपको एक पुनरावृत्ति देता है। आप लूप के बाहर अन्य पैटर्न में पुनरावृत्ति का उपयोग कर सकते हैं।

student = {"name": "Daniel", "student_id": 2222}

for key,value in student.items():
    print(key,value)

('student_id', 2222)
('name', 'Daniel')

for key,value in student.iteritems():
    print(key,value)

('student_id', 2222)
('name', 'Daniel')

studentIterator = student.iteritems()

print(studentIterator.next())
('student_id', 2222)

print(studentIterator.next())
('name', 'Daniel')

-5

python 2 में dict.iteritems (), python 3 में dict.items () के बराबर है।


2
यह गलत है। पिछले उत्तरों में पहले ही अंतर स्पष्ट किया जा चुका है।
वॉल्टह
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.