पुनरावृत्तियों और जनरेटर के बीच अंतर क्या है? जब आप प्रत्येक मामले का उपयोग करेंगे तो कुछ उदाहरण सहायक होंगे।
पुनरावृत्तियों और जनरेटर के बीच अंतर क्या है? जब आप प्रत्येक मामले का उपयोग करेंगे तो कुछ उदाहरण सहायक होंगे।
जवाबों:
iterator
एक अधिक सामान्य अवधारणा है: कोई भी वस्तु जिसकी कक्षा में एक next
विधि है ( __next__
पायथन 3 में) और एक __iter__
विधि जो करती है return self
।
हर जेनरेटर एक इटरेटर है, लेकिन इसके विपरीत नहीं। एक जनरेटर एक फ़ंक्शन को कॉल करके बनाया गया है जिसमें एक या एक से अधिक yield
अभिव्यक्ति ( yield
बयान, पायथन 2.5 और पूर्व में) हैं, और एक ऑब्जेक्ट है जो पिछले पैराग्राफ की परिभाषा से मिलता है iterator
।
आप एक जनरेटर के बजाय एक कस्टम पुनरावृत्ति का उपयोग करना चाह सकते हैं, जब आपको कुछ जटिल राज्य बनाए रखने वाले व्यवहार के साथ एक वर्ग की आवश्यकता होती है, या next
( __iter__
और __init__
) के अलावा अन्य तरीकों को उजागर करना चाहते हैं । सबसे अधिक बार, एक जनरेटर (कभी-कभी, पर्याप्त रूप से सरल आवश्यकताओं के लिए, एक जनरेटर अभिव्यक्ति ) पर्याप्त होता है, और यह कोड के लिए सरल होता है क्योंकि राज्य के रखरखाव (उचित सीमा के भीतर) मूल रूप से निलंबित और फिर से शुरू होने वाले फ्रेम द्वारा "आपके लिए" किया जाता है।
उदाहरण के लिए, एक जनरेटर जैसे:
def squares(start, stop):
for i in range(start, stop):
yield i * i
generator = squares(a, b)
या समकक्ष जनरेटर अभिव्यक्ति (जीनएक्सपी)
generator = (i*i for i in range(a, b))
एक कस्टम पुनरावृत्ति के रूप में बनाने के लिए अधिक कोड ले जाएगा:
class Squares(object):
def __init__(self, start, stop):
self.start = start
self.stop = stop
def __iter__(self): return self
def next(self): # __next__ in Python 3
if self.start >= self.stop:
raise StopIteration
current = self.start * self.start
self.start += 1
return current
iterator = Squares(a, b)
लेकिन, निश्चित रूप से, वर्ग के साथ Squares
आप आसानी से अतिरिक्त तरीकों की पेशकश कर सकते हैं, अर्थात
def current(self):
return self.start
यदि आपको अपने आवेदन में ऐसी अतिरिक्त कार्यक्षमता के लिए कोई वास्तविक आवश्यकता है।
for ... in ...:
एक समारोह का हिस्सा हो जाएगा , या आप कॉल कर रहे होंगेiter.next()
for..in
सिंटैक्स का उपयोग करने की कोशिश में त्रुटि हो रही थी । शायद मैं कुछ याद कर रहा था, लेकिन यह कुछ समय पहले था, मैं हल नहीं करता अगर मैं हल करता हूं। धन्यवाद!
पुनरावृत्तियों और जनरेटर के बीच अंतर क्या है? जब आप प्रत्येक मामले का उपयोग करेंगे तो कुछ उदाहरण सहायक होंगे।
सारांश में: Iterators वस्तुओं है कि एक कर रहे हैं __iter__
और एक __next__
( next
पायथन में 2) विधि। जनरेटर Iterators के उदाहरण बनाने के लिए एक आसान, अंतर्निहित तरीका प्रदान करते हैं।
इसमें उपज के साथ एक फ़ंक्शन अभी भी एक फ़ंक्शन है, जिसे जब बुलाया जाता है, तो जनरेटर ऑब्जेक्ट का एक उदाहरण देता है:
def a_function():
"when called, returns generator object"
yield
एक जनरेटर अभिव्यक्ति भी एक जनरेटर देता है:
a_generator = (i for i in range(0))
अधिक गहराई से व्याख्या और उदाहरण के लिए, पढ़ते रहें।
विशेष रूप से, जनरेटर पुनरावृत्ति का एक उपप्रकार है।
>>> import collections, types
>>> issubclass(types.GeneratorType, collections.Iterator)
True
हम एक जनरेटर कई तरीके बना सकते हैं। ऐसा करने के लिए एक बहुत ही सामान्य और सरल तरीका एक फ़ंक्शन के साथ है।
विशेष रूप से, इसमें उपज वाला एक फ़ंक्शन एक फ़ंक्शन है, जिसे जब बुलाया जाता है, तो एक जनरेटर देता है:
>>> def a_function():
"just a function definition with yield in it"
yield
>>> type(a_function)
<class 'function'>
>>> a_generator = a_function() # when called
>>> type(a_generator) # returns a generator
<class 'generator'>
और एक जनरेटर, फिर से, एक Iterator है:
>>> isinstance(a_generator, collections.Iterator)
True
एक Iterator एक Iterable है,
>>> issubclass(collections.Iterator, collections.Iterable)
True
जिसके लिए एक __iter__
विधि की आवश्यकता होती है जो एक Iterator देता है:
>>> collections.Iterable()
Traceback (most recent call last):
File "<pyshell#79>", line 1, in <module>
collections.Iterable()
TypeError: Can't instantiate abstract class Iterable with abstract methods __iter__
पुनरावृत्तियों के कुछ उदाहरण अंतर्निर्मित ट्यूल, सूचियाँ, शब्दकोष, सेट, फ्रोज़न सेट, स्ट्रिंग्स, बाइट स्ट्रिंग्स, बाइट एरे, रेंज और मेमोरीव्यू हैं:
>>> all(isinstance(element, collections.Iterable) for element in (
(), [], {}, set(), frozenset(), '', b'', bytearray(), range(0), memoryview(b'')))
True
next
__next__
पायथन 2 में:
>>> collections.Iterator()
Traceback (most recent call last):
File "<pyshell#80>", line 1, in <module>
collections.Iterator()
TypeError: Can't instantiate abstract class Iterator with abstract methods next
और पायथन 3 में:
>>> collections.Iterator()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Iterator with abstract methods __next__
हम iter
फ़ंक्शन के साथ अंतर्निहित ऑब्जेक्ट्स (या कस्टम ऑब्जेक्ट) से पुनरावृत्तियों को प्राप्त कर सकते हैं :
>>> all(isinstance(iter(element), collections.Iterator) for element in (
(), [], {}, set(), frozenset(), '', b'', bytearray(), range(0), memoryview(b'')))
True
__iter__
विधि कहा जाता है जब आप एक के लिए लूप के साथ एक वस्तु का उपयोग करने का प्रयास। फिर __next__
विधि को प्रत्येक वस्तु को लूप से बाहर निकालने के लिए पुनरावृति वस्तु पर बुलाया जाता है। StopIteration
जब आप इसे समाप्त कर चुके हैं, तो इट्रेटर उठता है, और उस बिंदु पर इसका पुन: उपयोग नहीं किया जा सकता है।
Iterator के जेनरेटर के प्रकार खंड से बिल्ट-इन प्रकार के डॉक्यूमेंट के सेक्शन :
पायथन के जनरेटर इटरेटर प्रोटोकॉल को लागू करने का एक सुविधाजनक तरीका प्रदान करते हैं। यदि एक कंटेनर ऑब्जेक्ट की
__iter__()
विधि को एक जनरेटर के रूप में लागू किया जाता है, तो यह स्वचालित रूप से एक इट्रेटर ऑब्जेक्ट (तकनीकी रूप से, एक जनरेटर ऑब्जेक्ट)__iter__()
औरnext()
(__next__()
पायथन 3 में) विधियों की आपूर्ति करेगा । उपज अभिव्यक्ति के लिए प्रलेखन में जनरेटर के बारे में अधिक जानकारी प्राप्त की जा सकती है।
(महत्व दिया।)
तो इससे हमें पता चलता है कि जेनरेटर एक (सुविधाजनक) प्रकार का Iterator है।
आप ऑब्जेक्ट को बना सकते हैं जो Iterator प्रोटोकॉल को लागू करता है या आपकी स्वयं की ऑब्जेक्ट को बढ़ाकर या बढ़ाकर।
class Yes(collections.Iterator):
def __init__(self, stop):
self.x = 0
self.stop = stop
def __iter__(self):
return self
def next(self):
if self.x < self.stop:
self.x += 1
return 'yes'
else:
# Iterators must raise when done, else considered broken
raise StopIteration
__next__ = next # Python 3 compatibility
लेकिन ऐसा करने के लिए जेनरेटर का उपयोग करना आसान है:
def yes(stop):
for _ in range(stop):
yield 'yes'
या शायद सरल, एक जेनरेटर अभिव्यक्ति (सूची बोध के समान काम करता है):
yes_expr = ('yes' for _ in range(stop))
वे सभी एक ही तरीके से उपयोग किए जा सकते हैं:
>>> stop = 4
>>> for i, y1, y2, y3 in zip(range(stop), Yes(stop), yes(stop),
('yes' for _ in range(stop))):
... print('{0}: {1} == {2} == {3}'.format(i, y1, y2, y3))
...
0: yes == yes == yes
1: yes == yes == yes
2: yes == yes == yes
3: yes == yes == yes
जब आप पायथन ऑब्जेक्ट को एक ऑब्जेक्ट के रूप में विस्तारित करने की आवश्यकता हो तो आप सीधे इटरेटर प्रोटोकॉल का उपयोग कर सकते हैं।
हालाँकि, अधिकांश मामलों में, आप yield
एक ऐसे फ़ंक्शन को परिभाषित करने के लिए उपयोग करने के लिए सबसे उपयुक्त हैं जो जेनरेटर इटरेटर लौटाता है या जेनरेटर एक्सप्रेशंस पर विचार करता है।
अंत में, ध्यान दें कि जनरेटर कोरटाइन के रूप में और भी अधिक कार्यक्षमता प्रदान करते हैं। मैं yield
विवरण के साथ जेनरेटर की व्याख्या करता हूं , "उत्तर" उपज "कीवर्ड क्या करता है?"
iterators:
इटरेटर ऐसी वस्तुएं हैं जो next()
अनुक्रम के अगले मूल्य प्राप्त करने के लिए विधि का उपयोग करती हैं।
जेनरेटर:
एक जनरेटर एक फ़ंक्शन है जो yield
विधि का उपयोग करके मूल्यों के अनुक्रम का उत्पादन या पैदावार करता है ।
next()
जनरेटर विधि पर प्रत्येक विधि कॉल ( f
उदाहरण के लिए : नीचे उदाहरण में) जनरेटर फ़ंक्शन द्वारा लौटाया गया ( foo()
उदाहरण के लिए : नीचे उदाहरण में फ़ंक्शन), क्रम में अगला मान उत्पन्न करता है।
जब एक जनरेटर फ़ंक्शन कहा जाता है, तो यह फ़ंक्शन के निष्पादन की शुरुआत के बिना एक जनरेटर ऑब्जेक्ट देता है। जब next()
विधि को पहली बार कॉल किया जाता है, तो फ़ंक्शन तब तक निष्पादित करना शुरू कर देता है जब तक कि वह उपज स्टेटमेंट तक नहीं पहुंचता है जो उपज का मूल्य लौटाता है। उपज अंतिम नज़र रखता है यानी याद रखता है। और दूसरा next()
कॉल पिछले मूल्य से जारी है।
निम्न उदाहरण उपज के बीच परस्पर क्रिया को प्रदर्शित करता है और जनरेटर ऑब्जेक्ट पर अगली विधि को कॉल करता है।
>>> def foo():
... print "begin"
... for i in range(3):
... print "before yield", i
... yield i
... print "after yield", i
... print "end"
...
>>> f = foo()
>>> f.next()
begin
before yield 0 # Control is in for loop
0
>>> f.next()
after yield 0
before yield 1 # Continue for loop
1
>>> f.next()
after yield 1
before yield 2
2
>>> f.next()
after yield 2
end
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
एक उत्तर जोड़ना क्योंकि मौजूदा उत्तरों में से कोई भी विशेष रूप से आधिकारिक साहित्य में भ्रम को संबोधित नहीं करता है।
जेनरेटर फ़ंक्शंस साधारण फ़ंक्शंस हैं जिनकेyield
बजाय काउपयोग करके परिभाषित कियागया हैreturn
। जब कहा जाता है, तो एक जनरेटर फ़ंक्शन एक जनरेटर ऑब्जेक्ट लौटाता है, जो एक प्रकार का पुनरावृत्ति है - इसकी एकnext()
विधि है। जब आप कॉल करते हैंnext()
, तो जनरेटर फ़ंक्शन द्वारा प्राप्त अगला मान वापस आ जाता है।
या तो फ़ंक्शन या ऑब्जेक्ट को "जनरेटर" कहा जा सकता है, जिसके आधार पर पायथन स्रोत दस्तावेज़ आप पढ़ते हैं। अजगर शब्दकोष जनरेटर कार्यों कहते हैं, जबकि अजगर विकी जनरेटर वस्तुओं निकलता है। अजगर ट्यूटोरियल उल्लेखनीय मतलब का प्रबंधन दोनों तीन वाक्यों के अंतरिक्ष में प्रयोग:
जनरेटर पुनरावृत्तियों को बनाने के लिए एक सरल और शक्तिशाली उपकरण है। उन्हें नियमित कार्यों की तरह लिखा जाता है, लेकिन जब भी वे डेटा वापस करना चाहते हैं तो उपज विवरण का उपयोग करते हैं। हर बार अगला () उस पर कॉल किया जाता है, जनरेटर फिर से शुरू होता है जहां इसे छोड़ दिया गया था (यह सभी डेटा मानों को याद करता है और कौन सा विवरण अंतिम बार निष्पादित किया गया था)।
पहले दो वाक्य जनरेटर कार्यों के साथ जनरेटर की पहचान करते हैं, जबकि तीसरा वाक्य जनरेटर वस्तुओं के साथ उनकी पहचान करता है।
इस सभी भ्रम के बावजूद, कोई स्पष्ट और अंतिम शब्द के लिए पायथन भाषा के संदर्भ की तलाश कर सकता है:
उपज अभिव्यक्ति का उपयोग केवल एक जनरेटर फ़ंक्शन को परिभाषित करते समय किया जाता है, और इसका उपयोग केवल फ़ंक्शन परिभाषा के शरीर में किया जा सकता है। फ़ंक्शन परिभाषा में उपज अभिव्यक्ति का उपयोग करना उस परिभाषा को सामान्य फ़ंक्शन के बजाय जनरेटर फ़ंक्शन बनाने के लिए पर्याप्त है।
जब एक जनरेटर फ़ंक्शन कहा जाता है, तो यह एक जनरेटर के रूप में जाना जाने वाला पुनरावृत्ति लौटाता है। वह जनरेटर तब एक जनरेटर फ़ंक्शन के निष्पादन को नियंत्रित करता है।
तो, औपचारिक और सटीक उपयोग में, "जनरेटर" अयोग्य का अर्थ है जनरेटर वस्तु, न कि जनरेटर फ़ंक्शन।
उपरोक्त संदर्भ पायथन 2 के लिए हैं, लेकिन पायथन 3 भाषा संदर्भ एक ही बात कहता है। हालाँकि, पायथन 3 शब्दावली कहती है कि
जनरेटर ... आमतौर पर एक जनरेटर फ़ंक्शन को संदर्भित करता है, लेकिन कुछ संदर्भों में एक जनरेटर पुनरावृत्ति को संदर्भित कर सकता है। ऐसे मामलों में जहां पूरा अर्थ स्पष्ट नहीं है, पूर्ण शब्दों का उपयोग अस्पष्टता से बचा जाता है।
हर कोई उदाहरण के साथ एक बहुत अच्छा और क्रियात्मक उत्तर है और मैं वास्तव में इसकी सराहना करता हूं। मैं सिर्फ उन लोगों के लिए कुछ छोटी पंक्तियों का उत्तर देना चाहता था जो अभी भी स्पष्ट रूप से स्पष्ट नहीं हैं:
यदि आप अपना स्वयं का पुनरावृत्त बनाते हैं, तो यह थोड़ा सा शामिल है - आपको एक वर्ग बनाना होगा और कम से कम पुनरावृति और अगले तरीकों को लागू करना होगा। लेकिन क्या होगा अगर आप इस परेशानी से नहीं गुजरना चाहते हैं और जल्दी से एक इटेरेटर बनाना चाहते हैं। सौभाग्य से, पायथन एक पुनरावृत्त को परिभाषित करने के लिए एक छोटा रास्ता प्रदान करता है। आपको केवल एक फ़ंक्शन को उपज के लिए कम से कम 1 कॉल के साथ परिभाषित करना होगा और अब जब आप उस फ़ंक्शन को कॉल करते हैं तो यह " कुछ " लौटाएगा जो एक पुनरावृत्ति की तरह काम करेगा (आप अगली विधि को कॉल कर सकते हैं और इसे लूप के लिए उपयोग कर सकते हैं)। इस चीज़ का कुछ नाम पाइथन है जिसका नाम जेनरेटर है
आशा है कि थोड़ा स्पष्ट करता है।
पिछले उत्तर इस तरह से चूक गए: एक जनरेटर में एक close
विधि है, जबकि विशिष्ट पुनरावृत्तियों नहीं है। close
विधि चलाता एक StopIteration
जनरेटर में अपवाद है, जो एक में पकड़ा जा सकता है finally
कि इटरेटर में खंड, कुछ सफाई को चलाने के लिए एक मौका मिलता है। यह अमूर्तता सरल पुनरावृत्तियों की तुलना में बड़े में सबसे अधिक उपयोगी है। एक जनरेटर को बंद कर सकता है क्योंकि एक फ़ाइल को बंद कर सकता है, इसके बारे में परेशान होने के बिना।
उस ने कहा, पहले प्रश्न के लिए मेरा व्यक्तिगत उत्तर होगा: चलने योग्य केवल एक __iter__
विधि है, ठेठ पुनरावृत्तियों में केवल एक __next__
विधि है, जनरेटर में एक __iter__
और एक दोनों __next__
अतिरिक्त हैं close
।
दूसरे प्रश्न के लिए, मेरा व्यक्तिगत जवाब होगा: एक सार्वजनिक इंटरफ़ेस में, मैं जनरेटर को बहुत अधिक पसंद करता हूं, क्योंकि यह अधिक लचीला है: close
विधि के साथ एक बड़ी रचना yield from
। स्थानीय रूप से, मैं पुनरावृत्तियों का उपयोग कर सकता हूं, लेकिन केवल अगर यह एक सपाट और सरल संरचना है (पुनरावृत्त आसानी से रचना नहीं करता है) और यदि यह मानने के कारण हैं कि अनुक्रम विशेष रूप से कम है, खासकर अगर इसे अंत तक पहुंचने से पहले रोका जा सकता है। मैं पुनरावृत्तियों को निम्न स्तर के आदिम के रूप में देखता हूं, सिवाय शाब्दिक के।
नियंत्रण प्रवाह मामलों के लिए, जनरेटर वादों के रूप में एक महत्वपूर्ण अवधारणा है: दोनों अमूर्त और रचना योग्य हैं।
__iter__
विधि है, कैसे एक पुनरावृत्ति आ सकती है __next__
? यदि वे पुनरावृत्त होने वाले हैं, तो मैं उनसे अपेक्षा करता हूं कि वे __iter__
भी जरूरी हैं ।
__iter__
को पुनरावृति पर केवल पुनरावृत्ती की आवश्यकता होती है, जिसके लिए केवल एक next
विधि ( __next__
Python3 में) की आवश्यकता होती है । कृपया उनके कार्यान्वयन के साथ मानकों (बतख टाइपिंग के लिए) को भ्रमित न करें (कैसे एक विशेष पायथन दुभाषिया ने इसे लागू किया)। यह जनरेटर कार्यों (परिभाषा) और जनरेटर ऑब्जेक्ट्स (कार्यान्वयन) के बीच भ्रम की तरह एक सा है। ;)
जनरेटर समारोह, जनरेटर वस्तु, जनरेटर:
पाइथन में एक जेनरेटर फंक्शन एक नियमित फंक्शन की तरह होता है लेकिन इसमें एक या अधिक yield
स्टेटमेंट्स होते हैं। Iterator वस्तुओं को यथासंभव आसान बनाने के लिए जनरेटर फ़ंक्शन एक महान उपकरण है। इटरेटर जनरेटर समारोह द्वारा वस्तु returend भी कहा जाता है जेनरेटर वस्तु या जेनरेटर ।
इस उदाहरण में मैंने एक जेनरेटर फंक्शन बनाया है जो जेनरेटर ऑब्जेक्ट देता है <generator object fib at 0x01342480>
। अन्य पुनरावृत्तियों की तरह, जेनरेटर ऑब्जेक्ट का उपयोग for
लूप में या अंतर्निहित फ़ंक्शन के साथ किया जा सकता है next()
जो जनरेटर से अगला मूल्य लौटाता है।
def fib(max):
a, b = 0, 1
for i in range(max):
yield a
a, b = b, a + b
print(fib(10)) #<generator object fib at 0x01342480>
for i in fib(10):
print(i) # 0 1 1 2 3 5 8 13 21 34
print(next(myfib)) #0
print(next(myfib)) #1
print(next(myfib)) #1
print(next(myfib)) #2
तो एक जनरेटर फ़ंक्शन Iterator ऑब्जेक्ट बनाने का सबसे आसान तरीका है।
Iterator :
प्रत्येक जनरेटर वस्तु एक पुनरावृत्ति है लेकिन इसके विपरीत नहीं है। कस्टम इटरेटर ऑब्जेक्ट तब बनाया जा सकता है जब उसकी क्लास इम्प्लीमेंट __iter__
और __next__
मेथड (इसे इटरेटर प्रोटोकॉल भी कहा जाता है)।
हालांकि, पुनरावृत्तियों को बनाने के लिए जनरेटर फ़ंक्शन का उपयोग करना बहुत आसान है क्योंकि वे अपनी रचना को सरल बनाते हैं, लेकिन एक कस्टम Iterator आपको अधिक स्वतंत्रता देता है और आप अपनी आवश्यकताओं के अनुसार अन्य तरीकों को भी लागू कर सकते हैं जैसा कि नीचे दिए गए उदाहरण में दिखाया गया है।
class Fib:
def __init__(self,max):
self.current=0
self.next=1
self.max=max
self.count=0
def __iter__(self):
return self
def __next__(self):
if self.count>self.max:
raise StopIteration
else:
self.current,self.next=self.next,(self.current+self.next)
self.count+=1
return self.next-self.current
def __str__(self):
return "Generator object"
itobj=Fib(4)
print(itobj) #Generator object
for i in Fib(4):
print(i) #0 1 1 2
print(next(itobj)) #0
print(next(itobj)) #1
print(next(itobj)) #1
नेड बैचेल्ड से उदाहरण और जनरेटर के लिए अत्यधिक अनुशंसित हैं
जनरेटर के बिना एक विधि जो संख्याओं के लिए भी कुछ करती है
def evens(stream):
them = []
for n in stream:
if n % 2 == 0:
them.append(n)
return them
एक जनरेटर का उपयोग करके
def evens(stream):
for n in stream:
if n % 2 == 0:
yield n
return
कथन की आवश्यकता नहीं हैevens
विधि (जनरेटर) को कॉल करना हमेशा की तरह है
num = [...]
for n in evens(num):
do_smth(n)
इटरेटर
पृष्ठों से भरी एक पुस्तक एक चलने योग्य है , एक बुकमार्क एक पुनरावृत्त है
और इस बुकमार्क को स्थानांतरित करने के अलावा कुछ भी नहीं करना है next
litr = iter([1,2,3])
next(litr) ## 1
next(litr) ## 2
next(litr) ## 3
next(litr) ## StopIteration (Exception) as we got end of the iterator
जनरेटर का उपयोग करने के लिए ... हमें एक फ़ंक्शन की आवश्यकता है
Iterator का उपयोग करने के लिए ... हमें ज़रूरत है next
औरiter
जैसा कि कहा गया है:
एक जनरेटर फ़ंक्शन एक पुनरावृत्त वस्तु देता है
Iterator का संपूर्ण लाभ:
मेमोरी में एक तत्व को एक बार स्टोर करें
आप समान डेटा के लिए दोनों दृष्टिकोणों की तुलना कर सकते हैं:
def myGeneratorList(n):
for i in range(n):
yield i
def myIterableList(n):
ll = n*[None]
for i in range(n):
ll[i] = i
return ll
# Same values
ll1 = myGeneratorList(10)
ll2 = myIterableList(10)
for i1, i2 in zip(ll1, ll2):
print("{} {}".format(i1, i2))
# Generator can only be read once
ll1 = myGeneratorList(10)
ll2 = myIterableList(10)
print("{} {}".format(len(list(ll1)), len(ll2)))
print("{} {}".format(len(list(ll1)), len(ll2)))
# Generator can be read several times if converted into iterable
ll1 = list(myGeneratorList(10))
ll2 = myIterableList(10)
print("{} {}".format(len(list(ll1)), len(ll2)))
print("{} {}".format(len(list(ll1)), len(ll2)))
इसके अलावा, यदि आप मेमोरी फ़ुटप्रिंट की जांच करते हैं, तो जनरेटर बहुत कम मेमोरी लेता है क्योंकि उसे एक ही समय में सभी मानों को मेमोरी में स्टोर करने की आवश्यकता नहीं होती है।
मैं विशेष रूप से पायथन के नए शौक के लिए बहुत ही सरल तरीके से लिख रहा हूं, हालांकि पायथन नीचे बहुत सारी चीजें करता है।
बहुत मूल के साथ शुरू करते हैं:
एक सूची पर विचार करें,
l = [1,2,3]
आइए एक समान फ़ंक्शन लिखें:
def f():
return [1,2,3]
o / p का print(l): [1,2,3]
& o / p काprint(f()) : [1,2,3]
आइए बनाते हैं लिस्ट को iterable: अजगर लिस्ट में हमेशा iterable होता है यानी आप जब चाहें इटरेटर लगा सकते हैं।
आइए सूची पर पुन: लागू करें:
iter_l = iter(l) # iterator applied explicitly
चलो एक फ़ंक्शन को चलने योग्य बनाते हैं, अर्थात एक समकक्ष जनरेटर फ़ंक्शन लिखते हैं।
जैसे ही आप कीवर्ड का परिचय देते हैं अजगर में yield
; यह एक जनरेटर फ़ंक्शन बन जाता है और इटरेटर को स्पष्ट रूप से लागू किया जाएगा।
नोट: हर जेनरेटर हमेशा लागू किए गए इटरेटर के साथ चलने योग्य होता है और यहाँ इम्परेटर इट्रिम क्रुक्स होता है इसलिए जनरेटर फंक्शन होगा:
def f():
yield 1
yield 2
yield 3
iter_f = f() # which is iter(f) as iterator is already applied implicitly
इसलिए यदि आपने देखा है, जैसे ही आपने फंक्शन एफ जनरेटर बनाया है, तो यह पहले से ही iter (f) है
अभी,
l वह सूची है, जो पुनरावृति विधि "iter" लागू करने के बाद, iter (l) बन जाती है
f पहले से ही iter है
यह थोड़े है आप इंट (एक्स) के लिए इंट कास्टिंग कर रहे हैं जो पहले से ही इंट है और यह इंट (एक्स) रहेगा।
उदाहरण के लिए ओ / पी:
print(type(iter(iter(l))))
है
<class 'list_iterator'>
यह कभी न भूलें कि यह पायथन है और C या C ++ नहीं है
इसलिए उपरोक्त स्पष्टीकरण से निष्कर्ष यह है:
सूची l ~ = iter (l)
जनरेटर फ़ंक्शन f == iter (f)