क्या वास्तव में पुनरावृत्त, पुनरावृत्त, और पुनरावृत्ति हैं?


442

पायथन में "पुनरावृत्ति", "पुनरावृत्त" और "पुनरावृत्ति" की सबसे बुनियादी परिभाषा क्या है?

मैंने कई परिभाषाएँ पढ़ी हैं, लेकिन मैं इसके सही अर्थ की पहचान करने में असमर्थ हूँ क्योंकि यह अभी भी नहीं डूबेगा।

क्या कोई आम आदमी की 3 परिभाषाओं में मेरी मदद कर सकता है?

जवाबों:


530

Iteration किसी वस्तु को प्रत्येक वस्तु को एक के बाद एक लेने के लिए एक सामान्य शब्द है। किसी भी समय आप लूप का उपयोग करते हैं, स्पष्ट या अंतर्निहित, वस्तुओं के समूह पर जाने के लिए, जो कि पुनरावृत्ति है।

अजगर में, iterable और इटरेटर विशिष्ट अर्थ है।

एक चलने योग्य एक ऐसी वस्तु है जिसमें एक __iter__विधि होती है जो एक पुनरावर्तक लौटाता है , या जो एक ऐसी __getitem__विधि को परिभाषित करता है जो शून्य से शुरू होने वाले अनुक्रमिक अनुक्रमों को ले सकती है (और IndexErrorतब बढ़ जाती है जब अनुक्रमणिका अब मान्य नहीं होती हैं)। एक तो iterable एक वस्तु है कि आप एक प्राप्त कर सकते है इटरेटर से।

एक पुनरावृत्ति एक next(पायथन 2) या __next__पायथन 3) विधि के साथ एक वस्तु है ।

जब भी आप पायथन में एक forलूप, या map, या सूची बोध, आदि का nextउपयोग करते हैं , तो इट्रेटर से प्रत्येक आइटम प्राप्त करने के लिए विधि को स्वचालित रूप से कहा जाता है , इस प्रकार पुनरावृत्ति की प्रक्रिया से गुजरना ।

सीखने की शुरुआत करने के लिए एक अच्छी जगह ट्यूटोरियल के पुनरावृत्तियों अनुभाग और मानक प्रकार पृष्ठ के पुनरावृत्त प्रकार अनुभाग होंगे । मूल बातें समझने के बाद, कार्यात्मक प्रोग्रामिंग HOWTO के पुनरावृत्तियों अनुभाग का प्रयास करें


1
ध्यान दें कि collections.abc.AsyncIteratorपरीक्षण __aiter__और __anext__विधियों के लिए। यह 3.6 में एक नया जोड़ है।
जानूस ट्रॉल्सन

1
@ jlh क्यों __len__जरूरी रूप से पुनरावृत्ति से बंधा होगा ? किसी चीज़ की लंबाई जानने से आपको उस पर पुनरावृति करने में कैसे मदद मिलेगी?
छायाकार

2
@shadowtalker यह जानने में मदद करेगा कि कौन से इंडेक्स वैध हैं, इसलिए आप जानते हैं कि किन इंडेक्स का इस्तेमाल किया जा सकता है __getitem__
jlh

4
@ ऐसा लगता है जैसे आप एक बहुत ही विचारशील dfeault व्यवहार का प्रस्ताव कर रहे हैं। विचार करें कि {'a': 'hi', 'b': 'bye'}2 की लंबाई है, लेकिन 0, 1, या 2. द्वारा अनुक्रमित नहीं किया जा सकता है
छायाकार

2
@shadowtalker। लेकिन एक हुक्मरान के पास एक __iter__तरीका होता है। मुझे लगता है कि jlh उन वस्तुओं का जिक्र कर रहा है जो विशेष रूप से चलने योग्य हैं क्योंकि वे परिभाषित करते हैं: "एक __getitem__विधि जो शून्य से शुरू होने वाले अनुक्रमिक अनुक्रमित ले सकती है"।
रिच

337

यहाँ व्याख्या मैं अजगर कक्षाओं को पढ़ाने में उपयोग कर रहा हूँ:

एक निष्क्रिय है:

  • कुछ भी जिस पर लूप किया जा सकता है (यानी आप किसी स्ट्रिंग या फाइल पर लूप कर सकते हैं) या
  • कुछ भी जो फॉर-लूप के दाईं ओर दिखाई दे सकता है: for x in iterable: ...या
  • आप जो कुछ भी कॉल कर सकते हैं, iter()वह एक Iterator को लौटा देगा: iter(obj)या
  • एक ऐसी वस्तु जो __iter__एक नए आईटर को लौटाती है, उसे परिभाषित करती है, या इसमें __getitem__अनुक्रमणित लुकअप के लिए उपयुक्त विधि हो सकती है ।

एक वस्तु एक वस्तु है:

  • उस राज्य के साथ, जहां यह याद है कि पुनरावृत्ति के दौरान,
  • एक __next__विधि के साथ :
    • पुनरावृति में अगला मान लौटाता है
    • राज्य को अगले मूल्य पर इंगित करने के लिए अद्यतन करता है
    • संकेत जब इसे बढ़ाकर किया जाता है StopIteration
  • और यह स्व-चलने योग्य है (इसका अर्थ है कि यह एक __iter__विधि है जो वापस लौटती है self)।

टिप्पणियाँ:

  • __next__अजगर 3 में विधि वर्तनी है nextअजगर 2 में, और
  • बिल्टिन फ़ंक्शन next()उस विधि को उस पर कॉल करता है जो उसके पास गई थी।

उदाहरण के लिए:

>>> s = 'cat'      # s is an ITERABLE
                   # s is a str object that is immutable
                   # s has no state
                   # s has a __getitem__() method 

>>> t = iter(s)    # t is an ITERATOR
                   # t has state (it starts by pointing at the "c"
                   # t has a next() method and an __iter__() method

>>> next(t)        # the next() function returns the next value and advances the state
'c'
>>> next(t)        # the next() function returns the next value and advances
'a'
>>> next(t)        # the next() function returns the next value and advances
't'
>>> next(t)        # next() raises StopIteration to signal that iteration is complete
Traceback (most recent call last):
...
StopIteration

>>> iter(t) is t   # the iterator is self-iterable

ताजा पुनरावृत्ति से आपका क्या अभिप्राय है?
lmiguelvargasf

13
@lmiguelvargasf "Fresh" के रूप में "नए और बेहूदा" के रूप में "थका हुआ या आंशिक रूप से भस्म" के विपरीत। विचार यह है कि एक नया पुनरावृत्ति प्रारंभ में शुरू होता है, जबकि आंशिक रूप से उपयोग किया जाने वाला पुनरावृत्त इसे उठाता है जहां इसे छोड़ा गया था।
रेमंड हेटिंगर

आपके 2, 3, और 4 गोलियां स्पष्ट रूप से संकेत करती हैं कि आप क्या मतलब है, विशिष्ट अजगर निर्माण या बिल्ट-इन या विधि कॉल के संदर्भ में। लेकिन पहली गोली ("कुछ भी जिसे खत्म किया जा सकता है") में स्पष्टता नहीं है। इसके अलावा, पहली गोली के लिए 2 गोली के साथ एक ओवरलैप लगता है, चूंकि 2 गोली forछोरों के बारे में है, और पहली गोली "ओवर लूपिंग" है। क्या आप इनका पता लगा सकते हैं?
झरने के स्रोतों

2
Pls पर विचार फिर से phrasing "के साथ कुछ भी कर सकते हैं अपने कॉल iter()के रूप में" कुछ भी आप के लिए पारित कर सकते हैं " iter()"
झरने के स्रोतों

98

उपर्युक्त उत्तर बहुत अच्छे हैं, लेकिन मैंने जो देखा है, उनमें से अधिकांश , मेरे जैसे लोगों के लिए पर्याप्त अंतर पर जोर नहीं देते हैं ।

इसके अलावा, लोग "एक्स एक ऑब्जेक्ट है जो __foo__()विधि है" जैसी परिभाषाएं डालकर "बहुत पाइथोनिक" प्राप्त करते हैं । इस तरह की परिभाषाएं सही हैं - वे बतख-टाइपिंग दर्शन पर आधारित हैं, लेकिन इसकी सरलता में अवधारणा को समझने की कोशिश करते समय तरीकों पर ध्यान केंद्रित होता है।

इसलिए मैं अपना संस्करण जोड़ता हूं।


प्राकृतिक भाषा में,

  • पुनरावृति तत्वों की एक पंक्ति में एक समय में एक तत्व लेने की प्रक्रिया है।

पायथन में,

  • iterable एक ऐसी वस्तु है जो, अच्छी तरह से, iterable है, जिसे सीधे शब्दों में कहें तो इसका मतलब है कि इसे iteration में इस्तेमाल किया जा सकता है, जैसे कि एक forलूप के साथ । कैसे? इटरेटर का उपयोग करके । मैं नीचे समझाता हूँ।

  • ... जबकि इटरेटर एक वस्तु है कि परिभाषित करता है कि कैसे वास्तव में क्या करने के लिए यात्रा - विशेष रूप से आगे क्या है तत्व। इसलिए इसकी next()विधि होनी चाहिए ।

Iterators स्वयं भी चलने योग्य हैं, इस भेद के साथ कि उनकी __iter__()विधि एक ही वस्तु ( self) लौटाती है , भले ही पिछली कॉल द्वारा इसके आइटम का उपभोग किया गया हो या नहीं next()


जब for x in obj:बयान देखता है तो पायथन दुभाषिया क्या सोचता है ?

देखो, एक forपाश। एक पुनरावृत्ति के लिए एक नौकरी की तरह लग रहा है ... चलो एक मिलता है। ... वहाँ यह objआदमी है, तो चलो उससे पूछते हैं।

"श्रीमान obj, क्या आपके पास इसका पुनरावृत्ति है?" (... कॉल iter(obj), जो कॉल करता है obj.__iter__(), जो खुशी से एक चमकदार नया पुनरावृत्ति करता है _i।)

ठीक है, यह आसान था ... चलो फिर चलना शुरू करते हैं। ( x = _i.next()... x = _i.next()...)

चूंकि श्री objइस परीक्षण में सफल रहे (कुछ विधि द्वारा एक वैध पुनरावर्तक लौटकर), हम उन्हें विशेषण के साथ पुरस्कृत करते हैं: अब आप उन्हें "चलने योग्य श्री obj" कह सकते हैं ।

हालाँकि, साधारण मामलों में, आपको सामान्य रूप से पुनरावृत्त और पुनरावृत्त होने से कोई लाभ नहीं होता है। तो आप केवल एक ही वस्तु को परिभाषित करते हैं , जो कि स्वयं का पुनरावृत्त भी है। (पायथन वास्तव में परवाह नहीं करता है कि उसके _iद्वारा सौंप दिया गया objथा वह सब चमकदार नहीं था, लेकिन सिर्फ objखुद के लिए था।)

यही कारण है कि अधिकांश उदाहरणों में मैंने देखा है (और जो मुझे बार-बार भ्रमित कर रहा था), आप देख सकते हैं:

class IterableExample(object):

    def __iter__(self):
        return self

    def next(self):
        pass

के बजाय

class Iterator(object):
    def next(self):
        pass

class Iterable(object):
    def __iter__(self):
        return Iterator()

हालांकि, ऐसे मामले भी हैं, जब आप पुनरावृत्त होने से अलग होने से लाभ उठा सकते हैं, जैसे कि जब आप एक पंक्ति में आइटम रखना चाहते हैं, लेकिन अधिक "शाप"। उदाहरण के लिए जब आप "वर्तमान" और "आगामी" तत्वों के साथ काम करना चाहते हैं, तो आपके पास दोनों के लिए अलग-अलग पुनरावृत्तियों हो सकते हैं। या एक विशाल सूची से कई धागे खींच रहे हैं: प्रत्येक के पास सभी वस्तुओं पर पार करने के लिए अपना स्वयं का इटर्वर हो सकता है। ऊपर @ रेमंड्स और @ ग्लॉगल के उत्तर देखें।

कल्पना कीजिए कि आप क्या कर सकते हैं:

class SmartIterableExample(object):

    def create_iterator(self):
        # An amazingly powerful yet simple way to create arbitrary
        # iterator, utilizing object state (or not, if you are fan
        # of functional), magic and nuclear waste--no kittens hurt.
        pass    # don't forget to add the next() method

    def __iter__(self):
        return self.create_iterator()

टिप्पणियाँ:

  • मैं फिर से दोहराऊंगा: पुनरावृत्त पुनरावृत्ति नहीं है । Iterator को forलूप में "स्रोत" के रूप में उपयोग नहीं किया जा सकता है । forलूप को मुख्य रूप से क्या चाहिए __iter__() (जो कुछ के साथ कुछ देता है next())।

  • बेशक, forकेवल पुनरावृत्ति लूप नहीं है, इसलिए ऊपर कुछ अन्य निर्माणों पर भी लागू होता है ( while...)।

  • Iterator की next()पुनरावृत्ति को रोकने के लिए StopIteration फेंक सकते हैं। हालांकि, यह हमेशा के लिए पुनरावृति कर सकता है या अन्य साधनों का उपयोग नहीं करता है।

  • उपरोक्त "विचार प्रक्रिया" में, _iवास्तव में मौजूद नहीं है। मैंने वह नाम बना लिया है।

  • पायथन 3.x में एक छोटा सा बदलाव है: next()विधि (बिल्ट-इन नहीं) अब कहा जाना चाहिए __next__()। हाँ, यह ऐसा ही होना चाहिए था।

  • आप इसे इस तरह भी सोच सकते हैं: चलने योग्य डेटा है, पुनरावृत्त अगले आइटम को खींचता है

अस्वीकरण: मैं किसी भी पायथन इंटरप्रेटर का डेवलपर नहीं हूं, इसलिए मैं वास्तव में नहीं जानता कि दुभाषिया "क्या सोचता है"। उपरोक्त कथनों का पूरी तरह से प्रदर्शन है कि कैसे मैं अन्य विषयों, प्रयोगों और पायथन नौसिखिया के वास्तविक जीवन के अनुभव से विषय को समझता हूं।


1
यह बहुत अच्छा है - लेकिन मैं अभी भी थोड़ा भ्रमित हूं। मैंने सोचा था कि आपका पीला बॉक्स कह रहा था कि एक forलूप को एक इटरेटर की जरूरत है ("देखो, एक लूप के लिए। इटरेटर के लिए एक नौकरी की तरह दिखता है ... चलो एक हो जाओ।")। लेकिन फिर आप अंत में नोट्स में कहते हैं कि "Iterator को एक forलूप में स्रोत के रूप में इस्तेमाल नहीं किया जा सकता है " ...?
रेसिंग टैडपोल

आप केवल passउन nextपरिभाषाओं के लिए कोड क्यों रखते हैं ? मैं आपको यह मानकर चलूंगा कि किसी को अगले को प्राप्त करने का तरीका लागू करना होगा, क्योंकि अगले को कुछ वापस करना होगा।
nealmcb

@nealmcb हां, मुझे लगता है कि मेरे अतीत का यही मतलब है। (यही सब के बाद के passलिए है ।)
एलोइस महदाल

@AloisMahdal आह, मैंने पहले उस उपयोग को नहीं देखा था। जब मैं देखता हूं pass, मुझे लगता है कि यह वाक्यात्मक कारणों से है। मैं सिर्फ दीर्घवृत्त वस्तु पर उत्तर भर में भाग गया, जो काफी दिलचस्प है: आप ..."टूडो बाद में" ब्लॉक को इंगित करने के लिए उपयोग कर सकते हैं । NotImplementedभी उपलब्ध है।
nealmcb

जबकि मुझे यह पसंद है कि आप एक पुनरावृत्त और एक पुनरावृत्ति के बीच अंतर पर जोर दे रहे हैं, यह उत्तर खुद का विरोधाभासी है। पहले आप लिखते हैं, 'Iterators स्वयं भी iterable हैं', (जो पाइथन प्रलेखन में लिखा गया है ) से मेल खाता है । लेकिन फिर बाद में आप लिखते हैं: ' पुनरावृत्त चलने योग्य नहीं है । Iterator को forलूप में "स्रोत" के रूप में उपयोग नहीं किया जा सकता है । मुझे आपके उत्तर की बात मिलती है, और यह अन्यथा पसंद है, लेकिन मुझे लगता है कि इसे ठीक करने से लाभ होगा।
रिच

22

एक चलने योग्य एक वस्तु है जिसमें एक __iter__()विधि है। यह संभवतः कई बार, जैसे कि list()औरtuple() एस ।

एक पुनरावृत्त वस्तु है जो पुनरावृत्त करता है। यह एक __iter__()विधि द्वारा लौटाया जाता है , स्वयं अपनी __iter__()विधि से लौटता है और एक next()विधि होती है (__next__() 3.x में)।

Iteration इस next()सम्मान को बुलाने की प्रक्रिया है । __next__()जब तक उठता हैStopIteration

उदाहरण:

>>> a = [1, 2, 3] # iterable
>>> b1 = iter(a) # iterator 1
>>> b2 = iter(a) # iterator 2, independent of b1
>>> next(b1)
1
>>> next(b1)
2
>>> next(b2) # start over, as it is the first call to b2
1
>>> next(b1)
3
>>> next(b1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> b1 = iter(a) # new one, start over
>>> next(b1)
1

तो क्या वास्तव में यह सिर्फ एक वस्तु है जो कंटेनर से होकर गुजरती है? क्या यह उपयोगी होगा?
द ऐक्रिसडैड

अक्सर, लेकिन हमेशा नहीं। एक जनरेटर, फ़ाइल या डेटाबेस कर्सर को केवल एक बार पुनरावृत्त किया जा सकता है और इस प्रकार वे अपने स्वयं के पुनरावृत्त होते हैं।
ग्लोगल

मुझे लगता है कि b2 को b1 से स्वतंत्र नहीं होना चाहिए? इस विशेष मामले के लिए, यह स्वतंत्र है, यकीन है कि मैं इसे स्वतंत्र नहीं बल्कि एक वैध भी बना सकता हूं Iterable
बिन

@ हाँ हाँ। जैसा कि Iteratorहमेशा होता है Iterableऔर अपना होता है Iterator, iter()जरूरी नहीं कि दो कॉल दो स्वतंत्र Iteratorएस दें।
9

13

यहाँ मेरा धोखा पत्र है:

 sequence
  +
  |
  v
   def __getitem__(self, index: int):
  +    ...
  |    raise IndexError
  |
  |
  |              def __iter__(self):
  |             +     ...
  |             |     return <iterator>
  |             |
  |             |
  +--> or <-----+        def __next__(self):
       +        |       +    ...
       |        |       |    raise StopIteration
       v        |       |
    iterable    |       |
           +    |       |
           |    |       v
           |    +----> and +-------> iterator
           |                               ^
           v                               |
   iter(<iterable>) +----------------------+
                                           |
   def generator():                        |
  +    yield 1                             |
  |                 generator_expression +-+
  |                                        |
  +-> generator() +-> generator_iterator +-+

प्रश्नोत्तरी: क्या आप देखते हैं कि कैसे ...

  1. हर पुनरावृत्त एक चलने योग्य है?
  2. एक कंटेनर वस्तु __iter__() विधि को जनरेटर के रूप में लागू किया जा सकता है?
  3. एक iterable कि एक __next__विधि है जरूरी एक पुनरावृत्ति नहीं है?

उत्तर:

  1. हर iterator में एक __iter__विधि होनी चाहिए । होने के __iter__लिए एक चलने के लिए पर्याप्त है। इसलिए हर पुनरावृत्त एक चलने योग्य है।
  2. जब __iter__यह कहा जाता है तो इसे एक पुनरावृत्तिकर्ता ( return <iterator>ऊपर दिए गए आरेख में) वापस करना चाहिए । जनरेटर को कॉल करना एक जनरेटर पुनरावृत्ति देता है जो एक प्रकार का पुनरावृत्ति है।

    class Iterable1:
        def __iter__(self):
            # a method (which is a function defined inside a class body)
            # calling iter() converts iterable (tuple) to iterator
            return iter((1,2,3))
    
    class Iterable2:
        def __iter__(self):
            # a generator
            for i in (1, 2, 3):
                yield i
    
    class Iterable3:
        def __iter__(self):
            # with PEP 380 syntax
            yield from (1, 2, 3)
    
    # passes
    assert list(Iterable1()) == list(Iterable2()) == list(Iterable3()) == [1, 2, 3]
  3. यहाँ एक उदाहरण है:

    class MyIterable:
    
        def __init__(self):
            self.n = 0
    
        def __getitem__(self, index: int):
            return (1, 2, 3)[index]
    
        def __next__(self):
            n = self.n = self.n + 1
            if n > 3:
                raise StopIteration
            return n
    
    # if you can iter it without raising a TypeError, then it's an iterable.
    iter(MyIterable())
    
    # but obviously `MyIterable()` is not an iterator since it does not have
    # an `__iter__` method.
    from collections.abc import Iterator
    assert isinstance(MyIterable(), Iterator)  # AssertionError

1
क्विज़ में, मुझे केवल 1 बुलेट पॉइंट समझ में आया। यानी पुनरावृत्ति एक चलने योग्य हो जाता है क्योंकि इसकी __iter__विधि होती है। क्या आप इस उत्तर को संपादित करके 2 और 3 अंक पर विस्तृत कर सकते हैं
18

@ एएनवी: जहां तक ​​मैं समझता हूं: पुन: 2: __iter__()एक पुनरावृत्तिकर्ता। एक जनरेटर एक पुनरावृत्ति है, इसलिए इसका उपयोग इस उद्देश्य के लिए किया जा सकता है। पुनः 3 .: मैं केवल यहां अनुमान लगा सकता हूं, लेकिन मुझे लगता है कि अगर __iter__()गायब है, या वापस नहीं आता है self, तो यह एक पुनरावृत्ति नहीं है, क्योंकि एक पुनरावृत्त __iter__()को वापस लौटना है self
6

10

मुझे नहीं पता कि यह किसी की मदद करता है लेकिन मैं हमेशा उन्हें समझने के लिए अपने सिर में अवधारणाओं की कल्पना करना पसंद करता हूं। इसलिए जैसा कि मेरा एक छोटा बेटा है, मैं ईंटों और सफेद कागज के साथ पुनरावृत्त / पुनरावृत्त अवधारणा की कल्पना करता हूं।

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

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

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

जब मैं एक IDLE में निम्नलिखित की कोशिश करता हूं तो मुझे अपनी शुरुआती गलती के बारे में पता चलता है और एक TypeError मिली:

 >>> X = [1,2,3,4,5]
 >>> next(X)
 Traceback (most recent call last):
    File "<pyshell#19>", line 1, in <module>
      next(X)
 TypeError: 'list' object is not an iterator

यहां सूची X हमारी ईंटों की किट थी, लेकिन कागज का सफेद टुकड़ा नहीं था। मुझे पहले एक पुनरावृत्ति खोजने की आवश्यकता थी:

>>> X = [1,2,3,4,5]
>>> bricks_kit = [1,2,3,4,5]
>>> white_piece_of_paper = iter(bricks_kit)
>>> next(white_piece_of_paper)
1
>>> next(white_piece_of_paper)
2
>>>

पता नहीं अगर यह मदद करता है, लेकिन यह मेरी मदद की। यदि कोई इस अवधारणा की पुष्टि / सुधार कर सकता है, तो मैं आभारी रहूंगा। इससे मुझे और सीखने में मदद मिलेगी।


6

Iterable : - कुछ जो चलने योग्य है वह चलने योग्य है; जैसे सीक्वेंस जैसे लिस्ट, स्ट्रिंग्स आदि। इसके अलावा या तो इसका __getitem__तरीका या __iter__तरीका है। अब यदि हम iter()उस ऑब्जेक्ट पर फ़ंक्शन का उपयोग करते हैं, तो हमें एक इट्रेटर मिलेगा।

Iterator : - जब हमें iter()फंक्शन से iterator ऑब्जेक्ट मिलता है ; हम एक-एक करके तत्वों को प्राप्त करने के लिए __next__()विधि (python3 में) या बस next()( python2 में) कहते हैं । इस वर्ग के इस वर्ग या उदाहरण को एक पुनरावृत्त कहा जाता है।

डॉक्स से: -

पुनरावृत्तियों का उपयोग पायथन करता है और पायथन को एकजुट करता है। पर्दे के पीछे, बयान के लिए iter() कंटेनर ऑब्जेक्ट पर कॉल  करता है। फ़ंक्शन एक पुनरावृत्त वस्तु देता है __next__() जो उस विधि को परिभाषित करता है  जो एक बार में कंटेनर में तत्वों तक पहुंचता है। जब अधिक तत्व नहीं होते हैं, तो  __next__() एक StopIteration अपवाद उठाता है जो लूप को समाप्त करने के लिए कहता है। आप  अंतर्निहित फ़ंक्शन __next__() का उपयोग करके विधि  को कॉल कर सकते हैं  next(); यह उदाहरण दिखाता है कि यह कैसे काम करता है:

>>> s = 'abc'
>>> it = iter(s)
>>> it
<iterator object at 0x00A1DB50>
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
>>> next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    next(it)
StopIteration

एक कक्षा से बाहर: -

class Reverse:
    """Iterator for looping over a sequence backwards."""
    def __init__(self, data):
        self.data = data
        self.index = len(data)
    def __iter__(self):
        return self
    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]


>>> rev = Reverse('spam')
>>> iter(rev)
<__main__.Reverse object at 0x00A1DB50>
>>> for char in rev:
...     print(char)
...
m
a
p
s

4

मुझे नहीं लगता है कि आप इसे प्रलेखन की तुलना में बहुत सरल पा सकते हैं , हालांकि मैं कोशिश करूँगा:

  • Iterable कुछ है कि किया जा सकता है दोहराया से अधिक। व्यवहार में इसका अर्थ आमतौर पर एक अनुक्रम होता है जैसे कुछ ऐसा जिसमें शुरुआत और अंत होता है और इसमें सभी वस्तुओं के माध्यम से जाने का रास्ता होता है।
  • आप Iterator को एक सहायक छद्म विधि (या छद्म-विशेषता) के रूप में सोच सकते हैं जो अगले (या पहले) आइटम को चलने योग्य में देता है (या रखता है) । (व्यवहार में यह सिर्फ एक वस्तु है जो विधि को परिभाषित करती है next())

  • इस शब्द की मरियम-वेबस्टर परिभाषा द्वारा Iteration को संभवतः सबसे अच्छा समझाया गया है :

बी: कंप्यूटर के अनुक्रम के पुनरावृत्ति एक निर्दिष्ट संख्या में या किसी शर्त के पूरा होने तक निर्देश देता है - पुनरावृत्ति की तुलना करें


3
iterable = [1, 2] 

iterator = iter(iterable)

print(iterator.__next__())   

print(iterator.__next__())   

इसलिए,

  1. iterableएक ऐसी वस्तु है जिसे लूप किया जा सकता है । जैसे सूची, स्ट्रिंग, टपल आदि।

  2. iterहमारे iterableऑब्जेक्ट पर फ़ंक्शन का उपयोग करके एक पुनरावृत्ति ऑब्जेक्ट लौटाएगा

  3. अब इस पुनरावृत्ति वस्तु का नाम विधि है __next__(पायथन 3 में, या सिर्फ nextपायथन 2 में) जिसके द्वारा आप पुनरावृत्त के प्रत्येक तत्व तक पहुँच सकते हैं

इसलिए, ABDEE CODE OF OUTPUT OF ABDEE CODE WILL BE:

1

2


3

Iterables में एक __iter__विधि होती है जो हर बार एक नया पुनरावृत्ति कर देती है ।

Iterators एक ऐसी __next__विधि लागू करते हैं जो अलग-अलग आइटम लौटाती है, और एक __iter__विधि जो वापस आती है self

इसलिए, पुनरावृत्तियाँ भी चलने योग्य हैं, लेकिन पुनरावृत्त पुनरावृत्त नहीं हैं।

लुसियानो रामल्हो, फ्लुएंट पायथन।


2

पुनरावृत्तियों और पुनरावृत्तियों से निपटने से पहले, चलने और चलने वाले को तय करने वाला प्रमुख कारक अनुक्रम है

अनुक्रम: अनुक्रम डेटा का संग्रह है

Iterable: Iterable अनुक्रम प्रकार की वस्तु है जो समर्थन __iter__विधि है।

Iter विधि: Iter पद्धति एक इनपुट के रूप में अनुक्रम लेती है और एक ऑब्जेक्ट बनाती है जिसे इट्रेटर के रूप में जाना जाता है

Iterator: Iterator ऐसी वस्तु हैं जो अगली विधि को कहते हैं और अनुक्रम के माध्यम से अनुप्रस्थ करते हैं। अगली विधि को कॉल करने पर यह उस वस्तु को लौटाता है जो वर्तमान में ट्रेस की गई है।

उदाहरण:

x=[1,2,3,4]

x एक अनुक्रम है जिसमें डेटा का संग्रह होता है

y=iter(x)

कॉल iter(x)करने पर यह केवल एक पुनरावर्तक लौटाता है, जब x ऑब्जेक्ट में पुनरावृति विधि होती है अन्यथा यह एक अपवाद बढ़ाता है। यदि वह पुनरावृति देता है तो y इसके लिए नियत है:

y=[1,2,3,4]

चूंकि y एक पुनरावृत्ति है इसलिए यह next()विधि का समर्थन करता है

अगली विधि को कॉल करने पर यह सूची के अलग-अलग तत्वों को एक-एक करके वापस करता है।

अनुक्रम के अंतिम तत्व को वापस करने के बाद अगर हम फिर से अगली विधि कहते हैं तो यह StopIteration त्रुटि को बढ़ाता है

उदाहरण:

>>> y.next()
1
>>> y.next()
2
>>> y.next()
3
>>> y.next()
4
>>> y.next()
StopIteration

बस एक अवलोकन: y = iter (x) बिल्कुल y = [1,2,3,4] नहीं है क्योंकि y अब एक इट्रेटर ऑब्जेक्ट है। शायद आपको यह स्पष्ट करने के लिए एक टिप्पणी जोड़ना चाहिए कि एक सूची नहीं है, लेकिन एक पुनरावृत्त वस्तु है या प्रतिनिधित्व को बदल दें।
कोएलहुडो

-6

अजगर में सब कुछ एक वस्तु है। जब किसी ऑब्जेक्ट को चलने योग्य कहा जाता है, तो इसका मतलब है कि आप संग्रह के रूप में ऑब्जेक्ट (यानी पुनरावृति) के माध्यम से कदम बढ़ा सकते हैं।

उदाहरण के लिए सारणीएं चलने योग्य हैं। आप उनके लिए एक लूप के साथ कदम रख सकते हैं, और इंडेक्स 0 से इंडेक्स एन तक जा सकते हैं, और एरे ऑब्जेक्ट माइनस 1 की लंबाई हो सकती है।

शब्दकोश (कुंजी / मूल्य के जोड़े, जिसे साहचर्य सरणियों भी कहा जाता है) भी पुनरावृत्त हैं। आप उनकी चाबियों के माध्यम से कदम रख सकते हैं।

जाहिर है कि जो वस्तुएं संग्रह नहीं हैं, वे चलने योग्य नहीं हैं। उदाहरण के लिए एक बूल ऑब्जेक्ट का केवल एक मूल्य है, ट्रू या गलत। यह चलने योग्य नहीं है (यह समझ में नहीं आएगा कि यह एक चलने योग्य वस्तु है)।

अधिक पढ़ें। http://www.lepus.org.uk/ref/companion/Iterator.xml


6
जो वस्तुएं संग्रह नहीं हैं, वे पुनरावृत्त नहीं हैं , यह आमतौर पर सत्य नहीं है। सिर्फ कुछ उदाहरण देने के लिए, जनरेटर चलने योग्य हैं, लेकिन संग्रह नहीं हैं, और iter()मानक संग्रह प्रकारों पर कॉल करके बनाए गए पुनरावृत्त ऑब्जेक्ट चलने-फिरने योग्य हैं, लेकिन स्वयं, संग्रह नहीं हैं।
मार्क अमेरी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.