Python-এ জেনারেটর এবং ইটারেটর দুটি গুরুত্বপূর্ণ কনসেপ্ট, যা মেমরি এবং কম্পিউটিং পারফরম্যান্সের উন্নতিতে সহায়ক। তারা মূলত লুপের মাধ্যমে তথ্য পুনরাবৃত্তি করে বের করার জন্য ব্যবহৃত হয়, কিন্তু তাদের কাজের ধরণ কিছুটা আলাদা। নিচে এই দুটি ধারণা বিস্তারিত ব্যাখ্যা করা হলো।
ইটারেটর (Iterator)
ইটারেটর একটি অবজেক্ট, যা একবারে একটি এলিমেন্ট বের করে আনার জন্য Python-এর __iter__() এবং __next__() মেথড সংজ্ঞায়িত করে। এটি সাধারণত বড় ডেটাসেট থেকে তথ্য পুনরাবৃত্তি করে বের করতে ব্যবহৃত হয়।
ইটারেটর তৈরি এবং ব্যবহার
যেকোনো ইটারেবল অবজেক্ট যেমন তালিকা, টাপল, স্ট্রিং ইত্যাদি থেকে ইটারেটর তৈরি করা সম্ভব। iter() ফাংশন ব্যবহার করে আমরা একটি ইটারেটর তৈরি করতে পারি এবং next() ফাংশন দিয়ে একের পর এক এলিমেন্ট বের করতে পারি।
# একটি তালিকা থেকে ইটারেটর তৈরি করা
my_list = [1, 2, 3, 4]
my_iterator = iter(my_list)
# next() ফাংশন দিয়ে ইটারেটরের এলিমেন্ট বের করা
print(next(my_iterator)) # Output: 1
print(next(my_iterator)) # Output: 2
print(next(my_iterator)) # Output: 3
print(next(my_iterator)) # Output: 4
# পরবর্তীতে next() কল করলে StopIteration এরর আসবে
কাস্টম ইটারেটর তৈরি
Python-এ আমরা __iter__() এবং __next__() মেথড সংজ্ঞায়িত করে একটি কাস্টম ইটারেটর ক্লাস তৈরি করতে পারি।
class MyIterator:
def __init__(self, max_value):
self.max = max_value
self.current = 0
def __iter__(self):
return self
def __next__(self):
if self.current < self.max:
self.current += 1
return self.current - 1
else:
raise StopIteration
# কাস্টম ইটারেটর ব্যবহার
my_iter = MyIterator(5)
for value in my_iter:
print(value) # Output: 0, 1, 2, 3, 4
জেনারেটর (Generator)
জেনারেটর ইটারেটরের একটি বিশেষ ধরনের ফর্ম যা ফাংশনের মাধ্যমে তৈরি করা হয় এবং yield কীওয়ার্ড ব্যবহার করে প্রতিটি মান প্রদান করে। এটি ডেটা একবারে একসাথে তৈরি না করে প্রতিটি চাহিদা অনুযায়ী এলিমেন্ট তৈরি করে, ফলে মেমরি সাশ্রয়ী হয়। যখনই yield ব্যবহার করা হয়, তখন ফাংশনটি তার বর্তমান অবস্থা স্মরণ করে এবং পুনরায় কল করা হলে সেখান থেকে পরবর্তী মান প্রদান করে।
জেনারেটর তৈরি করা
# একটি জেনারেটর ফাংশন যা নির্দিষ্ট সংখ্যক ক্রম প্রদান করে
def my_generator(n):
i = 0
while i < n:
yield i
i += 1
# জেনারেটর ফাংশন ব্যবহার
gen = my_generator(5)
for value in gen:
print(value) # Output: 0, 1, 2, 3, 4
yield বনাম return
- yield: ফাংশনটিকে জেনারেটর হিসেবে গড়ে তোলে এবং প্রতিবার যখন এটি কল করা হয় তখন পূর্বের স্থানে ফিরে আসে।
- return: ফাংশনের কাজ সম্পন্ন হলে ফাংশনটি শেষ করে এবং একটি একক মান প্রদান করে।
ইটারেটর এবং জেনারেটরের মধ্যে পার্থক্য
| বৈশিষ্ট্য | ইটারেটর (Iterator) | জেনারেটর (Generator) |
|---|---|---|
| তৈরি পদ্ধতি | __iter__() এবং __next__() মেথড দিয়ে তৈরি | yield ব্যবহার করে ফাংশনের মাধ্যমে তৈরি |
| মেমরি ব্যবহার | সম্পূর্ণ ডেটা মেমরিতে রাখে | প্রয়োজন অনুযায়ী ডেটা তৈরি করে (মেমরি সাশ্রয়ী) |
| ব্যবহার | সাধারণভাবে iter() এবং next() দিয়ে ব্যবহৃত | সরাসরি for লুপের সাথে ব্যবহারযোগ্য |
| স্টেট রিমেম্বার | নিজস্ব স্টেট ম্যানেজ করে | yield এর মাধ্যমে ফাংশনের স্টেট স্মরণ করে |
উদাহরণ: জেনারেটর দিয়ে ইনফাইনাইট সিকোয়েন্স তৈরি করা
# একটি ইনফাইনাইট সিকোয়েন্স জেনারেটর যা একের পর এক মান প্রদান করে
def infinite_sequence():
num = 0
while True:
yield num
num += 1
# ইনফাইনাইট সিকোয়েন্স ব্যবহার
gen = infinite_sequence()
for _ in range(5):
print(next(gen)) # Output: 0, 1, 2, 3, 4
উপসংহার
ইটারেটর এবং জেনারেটর দুটি খুবই শক্তিশালী কনসেপ্ট যা বড় আকারের ডেটাসেট নিয়ে কাজ করার সময় মেমরি এবং কম্পিউটিং পারফরম্যান্সের উন্নতি করতে সাহায্য করে। ইটারেটর সরাসরি ব্যবহার করা যায়, কিন্তু জেনারেটর স্মার্টভাবে মেমরি সাশ্রয় করে বড় ডেটাসেট নিয়ে কাজ করতে সক্ষম।