Lesson ৬ মিনিট পড়া

কম্প্রিহেনশন (Comprehensions)

একটি দারুণ লাইনেই পুরো কালেকশন বা সংগ্রহ তৈরি করে ফেলুন

লিস্ট কম্প্রিহেনশন — পাইথনিক শর্টকাট (List Comprehensions — The Pythonic Shortcut)

লিস্ট কম্প্রিহেনশন হলো অনেকটা ফ্যাক্টরির অ্যাসেম্বলি লাইনের মতো: একপ্রান্ত দিয়ে কাঁচামাল ঢোকে, সেগুলো রূপান্তরিত বা প্রসেস হয় এবং অন্য প্রান্ত দিয়ে প্রস্তুত পণ্য বের হয়ে আসে — এবং এই সবই ঘটে খুব সুন্দর একটি প্রক্রিয়ায়।

লুপ লেখা, একটি ফাঁকা লিস্ট তৈরি করা এবং তারপর একটি একটি করে আইটেম যোগ করার (append) বদলে, আপনি সম্পূর্ণ কাজটি এক লাইনে বর্ণনা করতে পারেন: [expression for item in iterable]

এর মূল প্যাটার্নটি হলো: [what_you_want for each_item in some_collection]

লিস্ট কম্প্রিহেনশন বনাম লুপ (List Comprehensions vs. Loops)

# The old way (loop)
squares_loop = []
for n in range(1, 6):
squares_loop.append(n ** 2)
print("Loop:", squares_loop)
# The comprehension way — same result, one line!
squares_comp = [n ** 2 for n in range(1, 6)]
print("Comp:", squares_comp)
# Transform strings
names = ["anika", "rafi", "sadia"]
shouting = [name.upper() for name in names]
print(shouting)
# Extract data
prices = [{"item": "coffee", "price": 4.50},
{"item": "muffin", "price": 3.25},
{"item": "juice", "price": 5.00}]
item_names = [p["item"] for p in prices]
print(item_names)
Output
Loop: [1, 4, 9, 16, 25]
Comp: [1, 4, 9, 16, 25]
['ALICE', 'BOB', 'CHARLIE']
['coffee', 'muffin', 'juice']

শর্ত ব্যবহার করে ফিল্টারিং (Filtering with Conditions)

আপনি একদম শেষে একটি if ক্লজ বা শর্ত জুড়ে দিয়ে ফিল্টার করতে পারেন যে কোন আইটেমগুলো এই অ্যাসেম্বলি লাইন পার করতে পারবে। কেবল সেই আইটেমগুলোই ফলাফলে অন্তর্ভুক্ত হবে, যেগুলোর ক্ষেত্রে শর্তটি True হয়।

প্যাটার্ন: [expression for item in iterable if condition]

আপনি চাইলে এক্সপ্রেশনের অংশে (for এর আগে) শর্তের ওপর ভিত্তি করে আইটেমগুলোকে ভিন্নভাবে রূপান্তর বা ট্রান্সফর্ম করার জন্য if/else ব্যবহার করতে পারেন।

ফিল্টারিং এবং কন্ডিশনাল এক্সপ্রেশন (Filtering & Conditional Expressions)

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Filter: only even numbers
evens = [n for n in numbers if n % 2 == 0]
print("Evens:", evens)
# Filter: words longer than 4 characters
words = ["hi", "python", "is", "absolutely", "cool"]
long_words = [w for w in words if len(w) > 4]
print("Long words:", long_words)
# Conditional expression (if/else in the expression)
labels = ["even" if n % 2 == 0 else "odd" for n in range(1, 6)]
print("Labels:", labels)
# Real-world: clean and validate emails
raw_emails = [" [email protected] ", "", "[email protected]", " ", "[email protected]"]
clean = [e.strip().lower() for e in raw_emails if e.strip()]
print("Valid emails:", clean)
Output
Evens: [2, 4, 6, 8, 10]
Long words: ['python', 'absolutely']
Labels: ['odd', 'even', 'odd', 'even', 'odd']
Valid emails: ['[email protected]', '[email protected]', '[email protected]']

ডিকশনারি এবং সেট কম্প্রিহেনশন (Dict & Set Comprehensions)

একই ধারণা ডিকশনারি এবং সেটের ক্ষেত্রেও কাজ করে! শুধু ব্র্যাকেটটি (bracket) পরিবর্তন করে দিন:

  • ডিকশনারি কম্প্রিহেনশন (Dict comprehension): {key: value for item in iterable} — কোলনসহ কার্লি ব্রেইস (curly braces) বা দ্বিতীয় বন্ধনী থাকে।
  • সেট কম্প্রিহেনশন (Set comprehension): {expression for item in iterable} — কার্লি ব্রেইস থাকে, তবে কোনো কোলন থাকে না।

ডিকশনারি এবং সেট কম্প্রিহেনশন (Dict & Set Comprehensions)

# Dict comprehension — word lengths
words = ["cat", "elephant", "dog", "hippopotamus"]
word_lengths = {w: len(w) for w in words}
print(word_lengths)
# Dict comprehension — flip keys and values
original = {"a": 1, "b": 2, "c": 3}
flipped = {v: k for k, v in original.items()}
print(flipped)
# Dict from two lists using zip()
countries = ["US", "UK", "JP"]
capitals = ["Washington", "London", "Tokyo"]
country_map = {c: cap for c, cap in zip(countries, capitals)}
print(country_map)
# Set comprehension — unique first letters
animals = ["ant", "bear", "cat", "ant", "butterfly", "cobra"]
first_letters = {a[0] for a in animals}
print(f"Unique first letters: {first_letters}")
Output
{'cat': 3, 'elephant': 8, 'dog': 3, 'hippopotamus': 12}
{1: 'a', 2: 'b', 3: 'c'}
{'US': 'Washington', 'UK': 'London', 'JP': 'Tokyo'}
Unique first letters: {'a', 'c', 'b'}

জেনারেটর এক্সপ্রেশন — অলস কাজিন (Generator Expressions — The Lazy Cousin)

জেনারেটর এক্সপ্রেশন (Generator expression) দেখতে অনেকটা লিস্ট কম্প্রিহেনশনের মতোই মনে হয়, তবে এটিতে [] এর বদলে () ব্যবহার করা হয়। এটি মেমোরিতে পুরো লিস্ট একবারে তৈরি করে না — এর বদলে এটি প্রয়োজন অনুযায়ী একবারে কেবল একটি আইটেম তৈরি করে দেয়। বিশাল ডেটাসেটের জন্য এটি চমৎকার, যেখানে পুরো লিস্ট তৈরি করতে গেলে মেমোরি ফুরিয়ে যাওয়ার ভয় থাকে।

জেনারেটর এক্সপ্রেশন (Generator Expressions)

# Generator expression — lazy evaluation
gen = (n ** 2 for n in range(1, 6))
print(type(gen)) # It's a generator, not a list!
# Consume one at a time
print(next(gen)) # 1
print(next(gen)) # 4
# Use directly in functions — no extra brackets needed!
total = sum(n ** 2 for n in range(1, 11))
print(f"Sum of squares 1-10: {total}")
# Memory comparison
import sys
big_list = [n for n in range(10_000)]
big_gen = (n for n in range(10_000))
print(f"List size: {sys.getsizeof(big_list):,} bytes")
print(f"Generator size: {sys.getsizeof(big_gen)} bytes")
Output
<class 'generator'>
1
4
Sum of squares 1-10: 385
List size: 85,176 bytes
Generator size: 200 bytes
Note: কম্প্রিহেনশন শক্তিশালী, কিন্তু এটিকে বাড়াবাড়ি পর্যায়ে নিয়ে যাবেন না। যদি আপনার কম্প্রিহেনশনটি প্রায় ৮০ ক্যারেক্টারের বেশি লম্বা হয়ে যায় বা এতে একাধিক if/for ক্লজ থাকে, তবে তার বদলে সাধারণ লুপ ব্যবহার করুন। অতিরিক্ত চালাকির চেয়ে কোড পড়ে সহজে বুঝতে পারার বিষয়টি সবসময় বেশি গুরুত্ব পায়।
চ্যালেঞ্জ

ছোট কুইজ

[x * 2 for x in [1, 2, 3]] কী তৈরি করে?
FunctionsFile I/O