ইটারেটর ও জেনারেটর

ইটারেটর

লুপ চাপ্টারে for লুপের ভিতরে আমরা ইটারেটরের হালকা-পাতলা প্রয়োগ দেখেছিলাম। আমরা দেখেছিলাম, for লুপ দিয়ে লিস্ট, টাপল, ডিকশনারি, স্ট্রিং এসব অবজেক্টকে ইটারেট করা যায়। ইটারেট করা যায় বলে এদেরকে ইটারেবল অবজেক্ট বলে। বিল্ট-ইন ফাংশন iter() এর ভিতর যদি আমরা কেন ইটারেবল অবজেক্টকে পাস করি তবে তা একটা ইটারেটর রিটার্ন করে। আর __next__() মেথড দিয়ে আমরা একটা ইটারেটরের পরবর্তী এলিমেন্ট বা আইটেমকে অ্যাক্সেস করতে পারি। সবগুলো আইটেম অ্যাক্সেস করতে করতে যখন আর কোন আইটেম বাকি থাকে না তখন পাইথন StopIteration এরর থ্রো করে। একটা উদাহরণ দেখা যাক।

>>> x = iter([1, 2, 3])
>>> x
<list_iterator object at 0x7f0f1694b1d0>
>>> x.__next__()
1
>>> x.__next__()
2
>>> x.__next__()
3
>>> x.__next__()
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    x.__next__()
StopIteration

আমরা এখন একটা ইটারেটর ক্লাস পয়দা করব। আমাদের এই ইটারেটর বিল্ট-ইন range() ফাংশনের মত কাজ করবে, তবে রিভার্সলি। মানে range(5) মানে তো 0, 1, 2, 3, 4। কিন্তু আমাদের তৈরি ইটারেটর ক্লাস এটাকে 5, 4, 3, 2, 1, 0 এরকম কিছু একটা বানাবে। তো চেষ্টা করা যাক।

class revrange:

    def __init__(self, n):
        self.n = n
        self.i = n

    def __iter__(self):
        return self

    def __next__(self):
        if self.n >= 0:
            if self.i == self.n:
                self.n = self.n - 1
                return self.i
            else:
                self.i = self.n
                self.n = self.n - 1
                return self.i
        else:
            raise StopIteration

for temp in revrange(5):
    print(temp)

আউটপুট

5
4
3
2
1
0

__iter__() মেথডটা কিন্তু খুব ইম্পরট্যান্ড এখানে। এটা ছাড়া পুরো ক্লাসটাই অচল হয়ে থাকবে।

জেনারেটর

জেনারেটর একটা ফাংশন। এই ফাংশনের কাজ হল yield স্টেটমেন্ট ব্যবহার করে সিকুয়েন্স পয়দা করা। এইদিক থেকে জেনারেটরও এক ধরনের ইটারেটর।

def revrange(n):
    while n >= 0:
        yield n
        n = n - 1

for temp in revrange(5):
    print(temp)

আউটপুট

5
4
3
2
1
0

যখন একটা জেনারেটর ফাংশন কল করা হয় তখন এটা ফাংশনের কোড এক্সিকিউট হবার আগেই একটা জেনারেটর অবজেক্ট রিটার্ন করে। যখন প্রথমবার __next__() মেথড কল করা হয় তখন ফাংশনের কোড এক্সিকিউট হওয়া শুরু করে। এক্সিকিউট হতে হতে যখন yield স্টেটমেন্ট অবধি পোঁছায় তখন __next__() মেথড ইয়েল্ডেড ভ্যালু রিটার্ন করে।

সহজ ভাষায় পাইথন ৩

বইটি পড়ার সময় প্রতিটি টপিক ধারাবাহিকভাবে বুঝে বুঝে পড়তে হবে এবং হাতে-কলমে অনুশীলন করতে হবে। কোন অংশ বুঝতে সমস্যা হলে ফেসবুক গ্রুপ পাইথন বাংলাদেশে সমস্যাটি পোস্ট করতে পারেন। এখান থেকে অতি দ্রুত সাহায্য-সহযোগীতা পাবেন আপনি।

results matching ""

    No results matching ""