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

পাইথনে ইফিশিয়েন্ট লুপিং-এর জন্য ইটেরেটর তৈরি করে ফাংশন (itertools)

বেশিরার প্রোগ্রামিং ল্যাঙ্গুয়েজের মতো পাইথনেও while এবং for স্টেটমেন্ট লুপিং কনস্ট্রাক্ট তৈরির জন্য আছে। for স্টেটমেন্ট বিশেষভাবে ইটারেবল যেমন লিস্ট, টাপল বা স্ট্রিং ট্রাভার্স করার জন্য উপকারী। আরও দক্ষ এবং দ্রুত ইটারেশন টুলস পাইথনের স্ট্যান্ডার্ড লাইব্রেরির itertools মডিউলে সংজ্ঞায়িত। এই ইটেরেটর বিল্ডিং ব্লকগুলো ফাংশনাল প্রোগ্রামিং ল্যাঙ্গুয়েজ যেমন Haskell এবং SML-এ একইরকম টুলসের পাইথনিক ইমপ্লিমেন্টেশন।

itertools মডিউলের ফাংশনগুলো তিন প্রকারের।

  • Infinite iterators (অনন্ত ইটেরেটর)
  • Finite iterators (সীমিত ইটেরেটর)
  • Combinatoric iterators (কম্বিনেটরিক ইটেরেটর)

অনন্ত সিকোয়েন্স জেনারেট করার ফাংশন

count()

এই ফাংশন একটি ইটেরেটর রিটার্ন করে যা শুরু মান থেকে সমান ব্যবধানযুক্ত মান দেয়। ফাংশনটি একটি অপশনাল step মান নিতে পারে সাকসেসিভ মান এই ইন্টারভাল দ্বারা বাড়াতে।

>>> from itertools import count
>>> for x in count(20):
        print(x)
>>> for x in count(100, 10):
        print(x)

প্রথম স্টেটমেন্ট ২০ থেকে শুরু होकर অনন্ত সিকোয়েন্স জেনারেট করবে এবং দ্বিতীয়টি ১০০ থেকে ১০ স্টেপিং ফ্রিকোয়েন্সি সহ সংখ্যা জেনারেট করবে। নোট করুন লুপগুলো অনন্ত এবং নিজ থেকে টার্মিনেট হবে না। Ctrl-C চাপায় টার্মিনেট হবে।

cycle()

এই ফাংশন দেওয়া ইটারেবল থেকে প্রতিটি এলিমেন্ট রিটার্ন করা শুরু করে এবং এর একটি কপি সংরক্ষণ করে। একবার এলিমেন্টগুলো খালি হলে, সংরক্ষিত কপির এলিমেন্টগুলো রিটার্ন করা হয় जिससे অনন্ত লুপ তৈরি হয়।

>>> from itertools import cycle
>>> for x in cycle("hello"):
        print(x)

স্ট্রিং-এর ক্যারেক্টারগুলো কীবোর্ড ইন্টারрап্ট Ctrl-C ইস্যু না হওয়া পর্যন্ত রিপিটিভলি প্রিন্ট হবে।

repeat()

এই ফাংশন আর্গুমেন্ট অবজেক্টটিকে বারবার রিটার্ন করে। যদি দ্বিতীয় আর্গুমেন্ট 'times' দেওয়া হয়, রিপিটিশন उतनी বার ঘটবে।

>>> from itertools import repeat
>>> for x in repeat(1):
        print(x)
>>> for x in repeat('hello', 10):
        print(x)

প্রথম লুপ ১ এন্ডলেসলি প্রিন্ট করবে। দ্বিতীয়টি 'hello' ১০ বার প্রিন্ট করবে।

সীমিত ইটেরেটর (সবচেয়ে ছোট ইনপুট সিকোয়েন্সে টার্মিনেট)

accumulate()

এই ফাংশনের দুটি প্যারামিটার। প্রথমটি একটি ইটারেবল (লিস্ট, টাপল বা স্ট্রিং)। দ্বিতীয় প্যারামিটার ডিফল্টভাবে operator.add() (operator মডিউলের ফাংশন যা স্ট্যান্ডার্ড অ্যাডিশন অপারেটর ইমপ্লিমেন্ট করে), কিন্তু যেকোনো অন্য ফাংশন হতে পারে যা দুটি নিউমেরিক প্যারামিটার গ্রহণ করে।

accumulate(sequence, func)

ইনপুট সিকোয়েন্সের প্রথম দুটি এলিমেন্ট func দ্বারা প্রসেস করা হয়। প্রসেসের ফলাফল পরবর্তী ইটেরেশনের জন্য প্রথম প্যারামিটার এবং func-এর দ্বিতীয় প্যারামিটার ইনপুট সিকোয়েন্সের তৃতীয় এলিমেন্ট। এই প্রসেস সিকোয়েন্স এক্সহাস্ট হওয়া পর্যন্ত রিপিট হয়। accumulate ফাংশন একটি ইটেরেটর রিটার্ন করে যেখানে প্রতিটি এলিমেন্ট সাকসেসিভ এলিমেন্ট প্রসেস করার এক্সকুমুলেটেড ফলাফল।

নিচের উদাহরণে, লিস্টের সংখ্যাগুলো ক্যুমুলেটিভলি যোগ করা হয়েছে। নোট করুন ডিফল্ট ফাংশন আর্গুমেন্ট হলো অ্যাড অপারেশন।

>>> from itertools import accumulate
>>> list(accumulate([1, 2, 3, 4, 5]))
[1, 3, 6, 10, 15]

আমরা accumulate() ফাংশনের দ্বিতীয় প্যারামিটার হিসেবে একটি ইউজার-ডিফাইনড ফাংশনও रखতে পারি।

>>> def multiply(x, y):
        return x * y
>>> list(accumulate([1, 2, 3, 4, 5], multiply))
[1, 2, 6, 24, 120]

এই আচরণ কিছুটা বিল্ট-ইন reduce() ফাংশনের মতো। reduce() ফাংশন শুধু এক্সকুমুলেশনের চূড়ান্ত ফলাফল রিটার্ন করে, কিন্তু accumulate() সব ইন্টারমিডিয়েট রেজাল্টের একটি ইটেরেটর বানায়।

chain()

এই ফাংশনের একাধিক ইটারেবল প্যারামিটার হিসেবে থাকতে পারে। এটি ফলাফল ইটেরেটরে প্রথম ইটারেবলের প্রতিটি এলিমেন্ট yield করে এবং পরেরটির দিকে এগিয়ে যায় যতক্ষণ না ইটারেবল প্যারামিটারগুলো এক্সহাস্ট হয়।

>>> from itertools import chain
>>> list(chain([10, 20], 'hello', range(4)))
[10, 20, 'h', 'e', 'l', 'l', 'o', 0, 1, 2, 3]

dropwhile()

এই ফাংশন একটি ইটেরেটর রিটার্ন করে ইটারেবল থেকে এলিমেন্ট ড্রপ করে যতক্ষণ না প্রিডিকেট ফাংশন আর্গুমেন্ট True রিটার্ন করে। যে মুহূর্তে ফাংশন False রিটার্ন করে, বাকি সব এলিমেন্ট ইটেরেটরে yield করা হয়।

>>> from itertools import dropwhile
>>> def iseven(x):
        if x % 2 == 0:
            return True
        else:
            return False
>>> list(dropwhile(iseven, [12, 90, 61, 4, 15]))
[61, 4, 15]

filterfalse()

এই ফাংশন একটি ইটেরেটর রিটার্ন করে সেই এলিমেন্টগুলো ফিল্টার আউট করে যাদের জন্য প্রিডিকেট ফাংশন False ফলাফল দেয়।

>>> from itertools import filterfalse
>>> def iseven(x):
        if x % 2 == 0:
            return True
        else:
            return False
>>> list(filterfalse(iseven, [12, 90, 61, 4, 15]))
[61, 15]

islice()

এই ফাংশন একটি ইটেরেটর বিল্ড করে ইটারেবল থেকে নির্দিষ্ট এলিমেন্ট সিলেক্ট করে। সিলেকশন ক্রাইটেরিয়া start, stop এবং step প্যারামিটার ডিপেন্ড করে। সিলেকশন start মান থেকে শুরু হয় এবং stop মান পর্যন্ত চলতে থাকে। যদি stop None হয়, ইটারেবল-এর শেষ পর্যন্ত যায়, অন্যথায় নির্দিষ্ট ইনডেক্সে সিলেকশন থামে। Step প্যারামিটার ডিফল্ট ১। এলিমেন্ট সিলেকশন step প্যারামিটার দ্বারা ইনক্রিমেন্ট হয়। কোনো প্যারামিটার নেগেটিভ হতে পারে না।

>>> from itertools import islice
>>> list(islice(range(10), 1, 5, 2))
[1, 3]
>>> list(islice(range(10), 0, None, 3))
[0, 3, 6, 9]
>>> list(islice(range(10), 5, None))
[5, 6, 7, 8, 9]
>>> list(islice(range(10), 5))
[0, 1, 2, 3, 4]

কম্বিনেটরিক ইটেরেটর

product()

এই ফাংশন একটি ইটেরেটর জেনারেট করে যা ইনপুট সিকোয়েন্সের এলিমেন্টের কারtezিয়ান প্রোডাক্ট। এটি নেস্টেড for লুপ কনস্ট্রাক্ট করার সমতুল্য, প্রতিটি ইটারেবল সিকোয়েন্স ট্রাভার্স করার জন্য একটি।

নিচের উদাহরণে লিস্ট কমপ্রিহেনশন টেকনিক ব্যবহার করে দুটি সিকোয়েন্সে দুটি নেস্টেড লুপ চালানো হয়েছে কারtezিয়ান প্রোডাক্ট বানাতে।

>>> [[x, y] for x in [1, 2, 3] for y in ['a', 'b', 'c']]
[[1, 'a'], [1, 'b'], [1, 'c'], [2, 'a'], [2, 'b'], [2, 'c'], [3, 'a'], [3, 'b'], [3, 'c']]

product() ফাংশন অনুরূপ ফলাফল দেয়।

>>> from itertools import product
>>> list(product([1, 2, 3], ['a', 'b', 'c']))
[(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b'), (2, 'c'), (3, 'a'), (3, 'b'), (3, 'c')]

permutations()

এই ফাংশন ইনপুট ইটারেবলের এলিমেন্টের সব সম্ভাব্য পারমুটেশন yield করে। প্রতিটি পারমুটেশনের দৈর্ঘ্য এই ফাংশনের দ্বিতীয় প্যারামিটার হিসেবে স্পেসিফাই করা যেতে পারে। না দেওয়া হলে দৈর্ঘ্য এক।

>>> list(permutations(range(1, 4), 2))
[(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]

combinations()

এই ফাংশন ইনপুট ইটারেবলের এলিমেন্টের সব সম্ভাব্য কম্বিনেশন yield করে। প্রতিটি পারমুটেশনের দৈর্ঘ্য এই ফাংশনের দ্বিতীয় প্যারামিটার হিসেবে স্পেসিফাই করা যেতে পারে। না দেওয়া হলে দৈর্ঘ্য এক।

>>> from itertools import combinations
>>> list(combinations(range(1, 4), 2))
[(1, 2), (1, 3), (2, 3)]

এই আর্টিকেলে পাইথন লাইব্রেরির itertools মডিউলে সংজ্ঞায়িত বিভিন্ন ইটেরেটর টুল পরিচয় করানো হয়েছে।

  1. পাইথন ল্যাম্বডা ফাংশন: একটি পরিচিতি

  2. পাইথনে অ্যানোনিমাস ফাংশন (Anonymous Functions)

  3. পাইথনে issubset() ফাংশন

  4. পাইথনে intersection() ফাংশন