পুনরুক্তি এবং জেনারেটরের মধ্যে পার্থক্য কী? আপনি যখন প্রতিটি কেস ব্যবহার করবেন তখন কয়েকটি উদাহরণ সহায়ক হবে।
পুনরুক্তি এবং জেনারেটরের মধ্যে পার্থক্য কী? আপনি যখন প্রতিটি কেস ব্যবহার করবেন তখন কয়েকটি উদাহরণ সহায়ক হবে।
উত্তর:
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) পদ্ধতি। জেনারেটরগুলি আইট্রেটারগুলির উদাহরণ তৈরি করার জন্য একটি সহজ, অন্তর্নির্মিত উপায় সরবরাহ করে।
এতে ফলন সহ একটি ফাংশন এখনও একটি ফাংশন, যাকে বলা হয়, একটি জেনারেটরের কোনও সামগ্রীর উদাহরণ দেয়:
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'>
এবং একটি জেনারেটর, আবার, একটি আইট্রেটার:
>>> isinstance(a_generator, collections.Iterator)
True
একজন আইট্রেটার একটি স্বচ্ছল,
>>> issubclass(collections.Iterator, collections.Iterable)
True
যার জন্য এমন একটি __iter__পদ্ধতি প্রয়োজন যা একটি আইট্রেটরকে ফেরত দেয়:
>>> 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পুনরাবৃত্তি উত্থাপিত হয় যখন আপনি এটি ক্লান্ত করে ফেলেছেন এবং এটি সেই সময়ে পুনরায় ব্যবহার করা যাবে না।
বিল্ট-ইন টাইপ ডকুমেন্টেশনের ইটারেটর প্রকার বিভাগের জেনারেটর প্রকার বিভাগ থেকে :
পাইথনের জেনারেটর পুনরায় প্রোটোকল প্রয়োগের জন্য একটি সুবিধাজনক উপায় সরবরাহ করে। যদি কোনও ধারক অবজেক্টের
__iter__()পদ্ধতিটি জেনারেটর হিসাবে প্রয়োগ করা হয় তবে এটি স্বয়ংক্রিয়ভাবে একটি পুনরাবৃত্ত বস্তু (প্রযুক্তিগতভাবে, একটি জেনারেটর বস্তু) সরবরাহ করবে__iter__()এবংnext()[__next__()পাইথন 3 ইন] পদ্ধতিগুলি সরবরাহ করবে। জেনারেটর সম্পর্কে আরও তথ্য ফলন প্রকাশের ডকুমেন্টেশনে পাওয়া যায়।
(সামনে জোর দাও.)
সুতরাং এটি থেকে আমরা জানতে পারি যে জেনারেটর হ'ল (সুবিধাজনক) ধরণের আইট্রেটার।
আপনি নিজের অবজেক্ট তৈরি বা প্রসারিত করে আইটেটর প্রোটোকল প্রয়োগ করে এমন বস্তু তৈরি করতে পারেন।
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কোনও জেনারেটর ইটারেটর ফিরিয়ে দেয় বা জেনারেটর এক্সপ্রেশন বিবেচনা করে এমন ফাংশনটি সংজ্ঞায়িত করতে আপনি সবচেয়ে উপযুক্ত suited
পরিশেষে, নোট করুন যে জেনারেটরগুলি কর্টাইন হিসাবে আরও বেশি কার্যকারিতা সরবরাহ করে। আমি জেনারেটরদের 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 গ্লোসারিটিতে বলা হয়েছে
জেনারেটর ... সাধারণত একটি জেনারেটর ফাংশন বোঝায়, তবে কিছু প্রসঙ্গে একটি জেনারেটরের পুনরায় উল্লেখ করতে পারে। যে ক্ষেত্রে উদ্দিষ্ট অর্থ পরিষ্কার নয়, সম্পূর্ণ পদ ব্যবহার করে অস্পষ্টতা এড়ানো যায়।
প্রত্যেকের উদাহরণ সহ একটি দুর্দান্ত এবং ভার্জিক উত্তর রয়েছে এবং আমি সত্যিই এটির প্রশংসা করি। আমি কেবলমাত্র এমন লোকদের জন্য একটি সংক্ষিপ্ত কয়েকটি লাইনের উত্তর দিতে চেয়েছিলাম যারা এখনও ধারণাগতভাবে যথেষ্ট পরিষ্কার নয়:
আপনি যদি নিজের আইটিরেটর তৈরি করেন তবে এটি কিছুটা জড়িত - আপনাকে একটি শ্রেণী তৈরি করতে হবে এবং কমপক্ষে ইটার এবং পরবর্তী পদ্ধতিগুলি প্রয়োগ করতে হবে। তবে আপনি যদি এই ঝামেলাটি অতিক্রম করতে না চান এবং দ্রুত একটি পুনরুক্তি তৈরি করতে চান তবে কী হয়। ভাগ্যক্রমে, পাইথন একটি পুনরুক্তি নির্ধারণের জন্য একটি শর্ট-কাট উপায় সরবরাহ করে provides আপনাকে যা করতে হবে তা হ'ল উত্পাদনের জন্য কমপক্ষে 1 টি কল দিয়ে একটি ফাংশন সংজ্ঞায়িত করা হবে এবং এখন আপনি যখন সেই ফাংশনটি কল করবেন তখন এটি " কিছু " ফিরে আসবে যা একটি পুনরুক্তির মতো কাজ করবে (আপনি পরবর্তী পদ্ধতিতে কল করতে পারেন এবং এটি লুপের জন্য ব্যবহার করতে পারেন)। পাইথনের এই জিনিসের একটি নাম রয়েছে জেনারেটর
আশা করি কিছুটা স্পষ্ট হয়ে যায়।
পূর্ববর্তী উত্তরগুলি এই সংযোজনটি মিস করেছে: একটি জেনারেটরের একটি closeপদ্ধতি রয়েছে, তবে সাধারণ পুনরাবৃত্তিকারীরা তা করেন না। closeপদ্ধতি আরম্ভ করে StopIterationজেনারেটরের মধ্যে ব্যতিক্রম, যা একটি ধরা হতে পারেfinally যে পুনরুক্তিকারীর মধ্যে দফা, কিছু ক্লিন-আপ চালানোর জন্য একটি সুযোগ পেতে। এই বিমূর্ততাটি সাধারণ পুনরাবৃত্তির চেয়ে বৃহত্তর ক্ষেত্রে এটি সবচেয়ে ব্যবহারযোগ্য করে তোলে। যে কোনও জেনারেটর বন্ধ করতে পারে যেহেতু কোনও ফাইল বন্ধ করতে পারে, নীচের বিষয়গুলি নিয়ে উদ্বিগ্ন না করে।
এটি বলেছিল, প্রথম প্রশ্নের আমার ব্যক্তিগত উত্তরটি হবে: পুনরাবৃত্তির একটি __iter__পদ্ধতি কেবল আছে, সাধারণ পুনরাবৃত্তির একটি থাকে__next__ পদ্ধতি কেবল থাকে, জেনারেটরের একটি __iter__এবং একটি __next__এবং অতিরিক্ত উভয় থাকে close।
দ্বিতীয় প্রশ্নের জন্য, আমার ব্যক্তিগত উত্তরটি হবে: একটি পাবলিক ইন্টারফেসে, আমি জেনারেটরগুলিকে অনেক বেশি পক্ষপাতী করি, যেহেতু এটি আরও স্থিতিস্থাপক: closeপদ্ধতিটি একটি বৃহত্তর সংশ্লেষের সাথেyield from । স্থানীয়ভাবে, আমি পুনরাবৃত্তকারীগুলি ব্যবহার করতে পারি, তবে কেবল যদি এটি সমতল এবং সাধারণ কাঠামো হয় (পুনরাবৃত্তিকারীরা সহজেই রচনা করে না) এবং যদি বিশ্বাস করার কোনও কারণ থাকে তবে ক্রমটি সংক্ষিপ্ততরটি খুব কম হলেও বিশেষত এটি শেষ হওয়ার আগেই বন্ধ হয়ে যেতে পারে। আমি পুনরাবৃত্তিকে আক্ষরিক হিসাবে বাদ দিয়ে নিম্ন স্তরের আদিম হিসাবে দেখি।
নিয়ন্ত্রণ প্রবাহের বিষয়গুলির জন্য, জেনারেটরগুলি প্রতিশ্রুতির মতোই একটি গুরুত্বপূর্ণ ধারণা: উভয়ই বিমূর্ত এবং কম্পোজেবল।
__iter__পদ্ধতি থাকে, কেবল পুনরাবৃত্তির কীভাবে আসতে পারে __next__? যদি তাদের পুনরাবৃত্তিযোগ্য বলে মনে করা হয়, তবে আমি অবশ্যই তাদের প্রয়োজনীয়তা অর্জনের প্রত্যাশা করব __iter__।
__iter__পুনরাবৃত্তিকে ফিরিয়ে আনতে কেবল পুনরায় পুনরায় চলন প্রয়োজন, যা কেবলমাত্র একটি nextপদ্ধতি ( __next__পাইথন 3 এ) প্রয়োজন। দয়া করে মান প্রয়োগগুলি (হাঁসের টাইপিংয়ের জন্য) তাদের বাস্তবায়নের সাথে বিভ্রান্ত করবেন না (কোনও নির্দিষ্ট পাইথন দোভাষী কীভাবে এটি প্রয়োগ করেছেন)। এটি কিছুটা জেনারেটর ফাংশন (সংজ্ঞা) এবং জেনারেটর অবজেক্টস (বাস্তবায়ন) এর মধ্যে বিভ্রান্তির মতো। ;)
জেনারেটর ফাংশন, জেনারেটর অবজেক্ট, জেনারেটর:
একটি জেনারেটর ফাংশন শুধু পাইথন মধ্যে একজন নিয়মিত ফাংশন মত কিন্তু এটা এক বা একাধিক রয়েছে yieldবিবৃতি। জেনারেটর ফাংশনগুলি আইট্রেটার অবজেক্টগুলি যথাসম্ভব সহজতর করার একটি দুর্দান্ত সরঞ্জাম । ইটারেটর জেনারেটরের ফাংশন দ্বারা বস্তুর 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
সুতরাং একটি জেনারেটর ফাংশন হ'ল একটি ইট্রেটর অবজেক্ট তৈরির সহজতম উপায়।
আইট্রেটার :
প্রতিটি জেনারেটর অবজেক্ট একটি পুনরাবৃত্তি হয় তবে বিপরীতে নয়। এর শ্রেণি প্রয়োগ __iter__এবং __next__পদ্ধতি (এটিরেটর প্রোটোকল নামে পরিচিত) যদি একটি কাস্টম পুনরাবৃত্তকারী অবজেক্ট তৈরি করা যায় ।
তবে, পুনরুক্তি তৈরির জন্য জেনারেটর ফাংশন ব্যবহার করা অনেক সহজ কারণ তারা তাদের নির্মাণকে সহজ করে তোলে তবে একটি কাস্টম আইট্রেটর আপনাকে আরও বেশি স্বাধীনতা দেয় এবং নীচের উদাহরণে প্রদর্শিত আপনার প্রয়োজন অনুসারে আপনি অন্যান্য পদ্ধতিও প্রয়োগ করতে পারেন।
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)
iterator
পুস্তক পৃষ্ঠাগুলির পূর্ণ একটি হল iterable , একটি বুকমার্ক একটি হল পুনরুক্তিকারীর
এবং এই বুকমার্কটির সরানো ছাড়া কিছুই করার নেই 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
যেমন বলা হয়েছে:
একটি জেনারেটর ফাংশন একটি পুনরুক্তিযোগ্য বস্তু প্রদান করে
আইট্রেটারের পুরো সুবিধা:
একটি উপাদান স্মৃতিতে একটি সময় সঞ্চয় করুন
আপনি একই ডেটার জন্য উভয় পদ্ধতির তুলনা করতে পারেন:
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]
ও / পি এর print(l): [1,2,3]& ও / পি এরprint(f()) : [1,2,3]
আসুন তালিকাটি পুনরাবৃত্তযোগ্য করে তুলুন: পাইথন তালিকায় সর্বদা পুনরাবৃত্ত হয় এর অর্থ আপনি যখনই চান পুনরাবৃত্তিকে প্রয়োগ করতে পারেন।
আসুন তালিকায় পুনরাবৃত্তি প্রয়োগ করুন:
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
সুতরাং আপনি যদি পর্যবেক্ষণ করেছেন, ফাংশন এফ জেনারেটর তৈরি করার সাথে সাথেই এটি ইতিমধ্যে ইটার (চ)
এখন,
l হল তালিকা, পুনরাবৃত্ত পদ্ধতি প্রয়োগ করার পরে "ইটার" এটি হয়ে যায়, ইটার (l)
চ ইতিমধ্যে ইটার (চ) রয়েছে, পুনরাবৃত্ত পদ্ধতি প্রয়োগ করার পরে "ইটার" এটি হয়ে যায়, ইটার (ইটার (চ)), যা আবার ইটার (চ) হয়
এটি এমন কি আপনি ইতিপূর্বে ইন্ট (এক্স) এর জন্য castালাই করছেন যা ইতিমধ্যে অন্তর্নিহিত এবং এটি ইনট (এক্স) থাকবে।
উদাহরণস্বরূপ ও / পি:
print(type(iter(iter(l))))
হয়
<class 'list_iterator'>
এটি পাইথন এবং সি বা সি ++ নয় কখনও ভুলে যাবেন না
সুতরাং উপরোক্ত ব্যাখ্যা থেকে উপসংহারটি হ'ল:
তালিকা l ~ = ইটার (l)
জেনারেটর ফাংশন f == ইটার (চ)