কম্পিউটার টিউটোরিয়াল

পাইথন ইটেরেটর: একটি গাইড

পাইথন ইটেরেটর তৈরির গাইড

ইটেরেটর পাইথনে সর্বত্র বিদ্যমান; বেসিক্স শিখতে গেলেও "ইটেরেটর" বা "ইটেরেবল" শব্দটা শুনতে পাবেন।

একটি ইটেরেটর হলো এমন একটি অবজেক্ট যার ওপর ইটারেট করা যায়। যদিও কিছু বিল্ট-ইন অবজেক্ট আছে যার ওপর ইটারেট করা যায়, আপনি নিজেও আপনার ইটেরেটর ডিফাইন করতে পারেন।

এই গাইডে, আমরা পাইথন ইটেরেটর, কীভাবে এগুলো কাজ করে, এবং কীভাবে আপনি আপনার কোডে এগুলো ব্যবহার করতে পারেন তা আলোচনা করব। আমরা আমাদের নিজস্ব ইটেরেটর কনস্ট্রাক্ট করব যাতে আপনি তাদের কোর ফিচারস একশনে শিখতে পারেন। এই গাইডের কোড পাইথন ৩.x ইনস্টলেশন کے সাথে কম্প্যাটিবল।

চলুন শুরু করি!

ইটেরেটর কী?

ইটেরেটর হলো olyan অবজেক্ট যার ওপর ইটারেট করা যায়। একটি ইটেরেটর সেই অবজেক্ট থেকে ডেটা রিটার্ন করে, একবারে এক আইটেম।

আপনি কোনো অবজেক্ট ইটেরেবল কিনা তা চেক করতে পারেন সেটিকে ফর লুপের মাধ্যমে চালিয়ে দেখতে; যদি আপনি অবজেক্টের মধ্য দিয়ে লুপ করতে পারেন, তবে মানে সেটি ইটেরেবল। স্ট্রিং, লিস্ট, টাপল, এবং ডিকশনারি ইটেরেবল অবজেক্টের বিল্ট-ইন ডেটা টাইপের উদাহরণ।

পাইথনে একটি ইটেরেটর অবজেক্টের দুটি মেথড থাকতে হবে:

  • __iter__(): এটি আপনাকে একটি ইটেরেটর রিট্রিভ করতে দেয়।
  • __next__(): এটি আপনাকে একটি ইটেরেটরে পরবর্তী ভ্যালু পেতে দেয়।

ইটেরেটরে __ আন্ডারস্কোর ব্যবহার করা হয় কারণ এগুলো স্পেশাল ফাংশন বোঝায়। একটি ইটেরেটর ডিফাইন করতে, আপনাকে এই দুটি স্পেশাল ফাংশন ব্যবহার করতে হবে। একসাথে, এগুলাকে ইটেরেটর প্রোটোকল বলা হয়। এই মেথডগুলো সাধারণত "ইটার এবং নেক্সট মেথড" হিসেবে উচ্চারিত হয়।

একটি ইনফিনিট ইটেরেটর কীভাবে বিল্ড করবেন

আমরা বেসিক্স দিয়ে শুরু করব: একটি ইনফিনিট ইটেরেটর বিল্ড করা। এটি ইটেরেটরের সবচেয়ে সিম্পল টাইপ। এটिटা সিম্পল যে এটি চিরকাল চলবে। আমরা এটি পরে টিউটোরিয়ালে ফিক্স করব।

চলুন Cakes নামে একটি ক্লাস ডিফাইন করি, যেটি আমাদের ইটেরেটর ক্লাস হবে:

class Cakes:
    def __init__(self, value):
        self.value = value

আমরা একটি __init__ মেথড ডিক্লেয়ার করেছি যেটি আমাদের ক্লাসের একটি অবজেক্ট ইনস্ট্যানশিয়েট হওয়ার সাথে সাথে এক্সিকিউট হবে। __init__ মেথডকে কনস্ট্রাক্টর বলা হয়। এই উদাহরণে, আমাদের __init__ মেথড একটি ভ্যালু নিতে পারে: value।

পরবর্তী, আমরা আমাদের ইটেরেটর প্রোটোকল তৈরি করব:

def __iter__(self):
    return self
def __next__(self):
    return self.value

__iter__ মেথড আমাদের ইটেরেটর অবজেক্ট রিট্রিভ করতে ব্যবহার হয়। __next__ মেথড আমাদের নির্দিষ্ট ইটেরেবল অবজেক্টের পরবর্তী ভ্যালু রিট্রিভ করতে দেয়।

চলুন আমাদের কোড যেন কাজ করছে কিনা তা নিশ্চিত করি। সেটি করার জন্য আমাদের ক্লাসের একটি অবজেক্ট ডিফাইন করি:

cake = Cakes(["Vanilla Sponge"])

এতক্ষণ পর্যন্ত ভালো! আপনি ভাবতে পারেন: কেন এই কোড কিছু করছে না? কারণ আমাদের ক্লাস শুধু একটি ইটেরেটর ফাংশন রিটার্ন করে।

আমাদের ইটেরেটর এর ওপর ইটারেট করতে হবে যেন চেক করা যায় সেটি কাজ করছে কিনা। আমরা ফর-ইন লুপ ব্যবহার করে এটি করতে পারি:

for c in cake:
    print(c)

আমাদের কোড রিটার্ন করে:

Vanilla Sponge
Vanilla Sponge
…

ভ্যানিলা স্পঞ্জের শাপ! এটা কনসোলে প্রিন্ট হতে থাকে। কী হচ্ছে? আমরা আমাদের প্রথম ইটেরেটর তৈরি করেছি। এটি খুব সিম্পল, কিন্তু কাজ করে।

পাইথনে ফর-ইন লুপ ব্যবহার করে ইটেরেটর টেস্ট করা

আমাদের ইটেরেটরকে উপকারী করার আগে, ফর-ইন লুপের কনসেপ্ট রিভাইজ করি। আমাদের লাস্ট উদাহরণে, আমরা আমাদের কোড টেস্ট করার জন্য একটি ফর-ইন লুপ লিখেছিলাম:

for c in cake:
    print(c)

একটি ফর-ইন লুপ কাজ করে যেভাবে: এটি প্রথম __iter__() মেথড ব্যবহার করে একটি অবজেক্টের একটি ইটেরেটর তৈরি করে। তারপর ফর-ইন লুপ __next__() কল করে যতক্ষণ না কোনো ভ্যালু রিটার্ন না হয়।

আপনি for-in লুপকে একটি সিম্পল while লুপ হিসেবে চিন্তা করতে পারেন। যতক্ষণ ইটেরেটর ভ্যালু রিটার্ন করতে পারে, ততক্ষণ ফর-ইন লুপ সেসব ভ্যালু রিটার্ন করবে।

একটি উপকারী ইটেরেটর তৈরি করা

আমাদের লাস্ট ইটেরেটর খুব উপকারী নয়। এটি শুধু একই ভ্যালু বারবার প্রিন্ট করে। তারপরও, এটি একটি ইটেরেটর: এটি একটি ইটেরেবল অবজেক্টের সকল অবজেক্ট পড়তে সক্ষম।

আমরা একটি ইটেরেটর তৈরি করব যা একটি পাইথন অ্যারের ওপর ইটারেট করবে। এই অ্যারে কেকের একটি লিস্ট ধারণ করে।

আমাদের ইটেরেটরকে ইনফিনিট्ली রিপিট হতে রोकতে, আমরা আমাদের ইটেরেবলে কতগুলো ভ্যালু আছে এবং আমাদের ইটেরেটর কতবার এক্সিকিউট हुआ তা ট্র্যাক রাখব। এটি আমাদের ইটেরেটরকে এক্সিকিউট হতে রক্ষা করবে যতক্ষণ না সেটি লিস্টের সকল আইটেমের মধ্য দিয়ে ইটারেট করে নেয়।

একটি নতুন পাইথন ফাইল খুলুন এবং নিচের কোড পেস্ট করুন:

class Cakes:
    def __init__(self, value):
        self.value = value
        self.max = len(value)
        self.count = 0
    def __iter__(self):
        return self
    def __next__(self):
        if self.count < self.max:
            to_return = self.value[self.count]
            self.count += 1
            return to_return
        else:
            raise StopIteration

এই ইটেরেটর আমাদের লাস্টটির চেয়ে কিছুটা জটিল। তাই আমরা আগে ইনফিনিট ইটেরেটর বানিয়েছিলাম। এই ইটেরেটরে, আমরা তিনটি ভ্যালু ইনিশিয়ালাইজ করেছি:

  • value: যে আইটেমের ওপর আমরা ইটারেট করতে চাই।
  • max: আমাদের ইটেরেবলে আইটেমের সংখ্যা।
  • count: আমাদের ইটেরেটর কতবার এক্সিকিউট হয়েছে।

আমাদের __next__() মেথডে, আমরা একটি "ইফ" স্টেটমেন্ট যোগ করেছি। এই স্টেটমেন্ট চেক করে যে আমাদের ইটেরেটর কতবার চালানো হয়েছে (count) সেটি আমাদের ইটেরেবলে ইটারেট করার আইটেমের সংখ্যা (max) থেকে কম কিনা।

যদি "count" "max" থেকে কম হয়, আমাদের ইটেরেটর ইটেরেবল অবজেক্টের পরবর্তী ভ্যালু খুঁজে বের করবে। তারপর আমাদের "count" ভেরিয়েবলে ১ যোগ করবে যাতে আমরা ট্র্যাক রাখতে পারি কতগুলো অবজেক্ট ইটারেট করার জন্য বাকি। তারপর, আমরা ক্যালকুলেট করা ভ্যালুটি রিটার্ন করি।

মনে রাখবেন যে, আমরা "count" ভেরিয়েবল ইনক্রিমেন্ট করার আগে "to_return" ভেরিয়েবলে একটি ভ্যালু অ্যাসাইন করি। এটি নিশ্চিত করে যে আমরা আমাদের ইটেরেটরের বর্তমান ইটারেশনের ভ্যালু অ্যাক্সেস করতে পারি।

যদি আমরা আমাদের লিস্টের প্রতিটি আইটেমের ওপর ইটারেট করে ফেলি, তবে একটি এক্সেপশন райজ হবে যাকে StopIteration বলা হয়। এটি আমাদের প্রোগ্রাম থামিয়ে দেয় একবার লিস্টের সকল আইটেমের মধ্য দিয়ে ইটারেট করলে।

চলুন দেখি আমাদের ইটেরেটর কাজ করছে কিনা। আপনার মেন প্রোগ্রামে নিচের কোড যোগ করুন এবং এক্সিকিউট করুন:

cake = Cakes(["Vanilla Sponge"])
for c in cake:
    print(c)

আমাদের কোড রিটার্ন করে:

Vanilla Sponge

আমাদের লিস্টে আর কিছু আইটেম যোগ করি এবং দেখি কী হয়:

cake = Cakes(["Vanilla Sponge", "Carrot", "Coffee"])
for c in cake:
    print(c)

আমাদের কোড রিটার্ন করে:

Vanilla Sponge
Carrot
Coffee

আমরা করলাম! আমরা সফলভাবে একটি ইটেরেটর তৈরি করেছি যা আমাদের কেকের লিস্টের মধ্য দিয়ে লুপ করে। এতদুর আসার জন্য আপনি একটি কেক - অথবা কাম কম একটি কাপকেক - এর যোগ্য!

উপসংহার

ইটেরেটর আপনাকে এমন অবজেক্ট তৈরির অনুমতি দেয় যাদের ওপর ইটারেট করা যায়। একটি ইটেরেটর একটি লিস্ট, একটি স্ট্রিং, বা অন্য কোনো ইটেরেবল অবজেক্টের মধ্য দিয়ে লুপ করে এবং একটি নির্দিষ্ট অ্যাকশন পারফর্ম করতে পারে।

আপনি কী চ্যালেঞ্জের জন্য রেডি? একটি ইটেরেটর তৈরি করুন যা সংখ্যার একটি লিস্টের মধ্য দিয়ে লুপ করে এবং প্রতিটি সংখ্যা দুগুন করে রিটার্ন করে।

এই ইটেরেটরের কোড আমাদের উপরের উদাহরণের মতোই হবে - এটিও ইটেরেটর প্রোটোকল ব্যবহার করবে - কিন্তু এটিকে মেন প্রোগ্রামে রিটার্ন করার আগে লিস্টের প্রতিটি সংখ্যা দুগুন করে দিতে হবে।

এখন আপনি পাইথনে নিজস্ব ইটেরেটর লিখতে এক্সপার্টের মতো রেডি!

  1. পাইথন ইন্টারপ্রেটার: ধাপে ধাপে গাইড

  2. পাইথন find() মেথড: একটি সম্পূর্ণ গাইড

  3. পাইথন প্রায়োরিটি কিউ: সম্পূর্ণ গাইড

  4. পাইথন ডিকশনারি values() মেথড: ভ্যালু রিট্রিভ এবং ইটারেশন গাইড