পাঠ ০৩ · ২৫-এর মধ্যে · মডিউল ১

List, Tuple ও Dictionary

Lists, tuples & dicts — collections
৭ মিনিট পড়া শুরু · Beginner ব্রাউজারে কোড চালান

এই পাঠে যা শিখবেন

  • list তৈরি, indexing, slicing — AI ডেটার দৈনন্দিন কাজ
  • tuple কেন আলাদা — immutability-র সুবিধা
  • dict — key দিয়ে দ্রুত lookup, JSON-এর সাথে natural fit
  • set — unique মান ও সদস্যপদ যাচাই
  • কোন collection কখন বেছে নেবেন

১ · List — ক্রমিক তালিকা

একাধিক value একসাথে রাখতে — সবচেয়ে বহুল ব্যবহৃত কালেকশন listListPython-এর সাজানো, পরিবর্তনযোগ্য, mixed-type কালেকশন। AI-তে batch ডেটা, log entry, sample collection-এ অপরিহার্য। NumPy array-এর "Python সমকক্ষ"।। বর্গ-বন্ধনীর ভেতরে comma-আলাদা মান।

Python
# list তৈরি
scores = [85, 92, 78, 67, 95]
fruits = ["আম", "জাম", "কাঁঠাল"]
mixed = [1, "দুই", 3.0, True]   # mixed type চলে

print(scores)
print(len(scores))         # দৈর্ঘ্য — 5

# Index — শূন্য থেকে শুরু
print(scores[0])           # 85 — প্রথম
print(scores[-1])          # 95 — শেষ
print(scores[-2])          # 67 — শেষ থেকে দুই

# Slicing — start:stop:step
print(scores[1:4])         # [92, 78, 67] — index 1,2,3
print(scores[:3])          # [85, 92, 78]
print(scores[::-1])        # উল্টো

    
Index ০ থেকে শুরু — scores[0] প্রথম। ঋণাত্মক index শেষ থেকে। Slicing start:stop stop exclusive — গুরুত্বপূর্ণ মনে রাখা।

২ · List পরিবর্তন

Python
fruits = ["আম", "জাম"]

fruits.append("কাঁঠাল")        # শেষে যোগ
fruits.insert(0, "লিচু")        # নির্দিষ্ট স্থানে
print(fruits)                  # ['লিচু', 'আম', 'জাম', 'কাঁঠাল']

fruits.remove("জাম")           # মান দিয়ে মুছে
print(fruits)

last = fruits.pop()            # শেষেরটা ফেরত ও মুছে
print(f"মোছা: {last}, অবশিষ্ট: {fruits}")

fruits.sort()                  # বর্ণানুক্রমিক
print(fruits)

    
List mutable — পরিবর্তন in-place হয়। scores.sort() পুরনো scores-কে বদলে দেয়। Original রাখতে চাইলে sorted(scores) — নতুন list ফেরত।

৩ · Tuple — অপরিবর্তনীয় তালিকা

Tuple দেখতে list-এর মতো — কিন্তু বন্ধনী (), এবং immutableImmutableএকবার তৈরির পরে পরিবর্তন করা যায় না। int, str, tuple, frozenset — Python-এর immutable type। dict-এর key, set-এর element হতে পারে।। তৈরির পর পরিবর্তন করা যায় না।

Python
# Tuple
point = (3, 4)
shape = (224, 224, 3)              # ছবির shape
rgb = (255, 0, 0)                  # লাল

print(point[0], point[1])

# Tuple unpacking — খুব Python-প্রিয়
x, y = point
print(f"x={x}, y={y}")

h, w, c = shape
print(f"height={h}, width={w}, channels={c}")

# পরিবর্তনের চেষ্টা — error
try:
    point[0] = 10
except TypeError as e:
    print("ভুল:", e)

    
List = whiteboard, লিখুন-মুছুন। Tuple = পাথরে খোদাই, একবারই। কেন কাজে লাগে? কারণ পরিবর্তন না হলে — ক্যাশ করা যায়, dict-এর key হতে পারে, multi-thread-এ নিরাপদ।

৪ · Dictionary — key থেকে value

ফোনবুকের মতো — নাম দিয়ে নম্বর খোঁজা। {key: value} — Python-এর সবচেয়ে শক্তিশালী collection।

Python
# Dictionary তৈরি
student = {
    "name": "ফাহিম",
    "age": 20,
    "scores": [85, 92, 78],
    "is_active": True
}

# Access
print(student["name"])
print(student.get("phone", "নেই"))   # default — KeyError এড়াতে

# Add/update
student["city"] = "ঢাকা"
student["age"] = 21
print(student)

# Iterate
for key, value in student.items():
    print(f"{key}: {value}")

    
dict["key"] না থাকলে error। dict.get("key", default) safe। Python 3.7+ থেকে dict insertion order সংরক্ষণ করে।

৫ · Set — unique সদস্য

Python
# Duplicate বাতিলে
words = ["AI", "ML", "AI", "DL", "ML"]
unique = set(words)
print(unique)              # {'AI', 'ML', 'DL'}

# সদস্যপদ যাচাই — O(1), দ্রুত
vocab = {"king", "queen", "man", "woman"}
print("queen" in vocab)    # True
print("apple" in vocab)    # False

# Set অপারেশন — গণিতের set theory
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a | b)               # union
print(a & b)               # intersection
print(a - b)               # difference

    
কোন collection কখন বাছবেন? Decision tree order গুরুত্বপূর্ণ? Position matters? না key-value আছে? Need lookup? হ্যাঁ না dict {k: v} set {a, b, c} হ্যাঁ পরিবর্তন হবে? Will mutate? হ্যাঁ না list [a, b, c] tuple (a, b, c) দৈনন্দিন AI কাজে ৯০%-এই list ও dict
চারটি collection — চার ধরনের কাজে। সিদ্ধান্ত নেওয়ার দুটি প্রশ্ন।

৬ · Performance — কোনটা কত দ্রুত?

AI-তে millions of items নিয়ে কাজ করতে হয়। তখন collection-এর choice = ১০০× speedup।

  • List: x in lst — O(n), ধীর। index access — O(1)।
  • Tuple: list-এর মতো, কিন্তু একটু কম মেমোরি।
  • Dict: x in d, d[k] — O(1), গড়ে। hash table।
  • Set: x in s — O(1)। membership check-এর রাজা।
১০ লক্ষ word-এর মধ্যে "queen" আছে কিনা? list-এ ১ সেকেন্ড। set-এ ১ মাইক্রোসেকেন্ড। ১০ লক্ষ গুণ দ্রুত!

৭ · AI-তে এই collections-এর ব্যবহার

  • list: training samples, batch, loss history per epoch।
  • tuple: tensor shape (batch, channels, height, width), return multi-value।
  • dict: JSON config, model state_dict, hyperparameter, vocabulary mapping।
  • set: unique label, vocabulary, train/val split index।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ List ও tuple দুটোই sequence — তাহলে আলাদা type কেন? "Immutable হলে কিছু ক্ষেত্রে ভাল" — কোন ক্ষেত্রে ও কেন? ভাষার ডিজাইনে এই trade-off কীভাবে আসে?

এই প্রশ্নটি আসলে immutability নিয়ে — programming language design-এর গভীরতম প্রশ্ন। Functional programming-এর পুরো philosophy এর উপরে দাঁড়ানো।

Immutability-র সুবিধা:

  • Hashable: tuple dict-এর key হতে পারে, list পারে না। যেমন: {(0, 0): "origin"} — coordinate-key dict।
  • Thread safe: পরিবর্তন হবে না — তাই দু'জন একসাথে পড়লেও race condition নেই।
  • Caching/memoization: arg immutable হলে — function output cache করা যায়।
  • Defensive copy লাগে না: caller-এর tuple bug-এ change হবে না — confidence।
  • Functional purity: input বদলায় না → side-effect-free → test সহজ।

List-এর সুবিধা:

  • In-place modification — বড় list copy করতে হয় না।
  • append, sort, reverse — incremental কাজে natural।
  • Memory pre-allocation — Python পরবর্তী append-এর জন্য জায়গা রাখে।

কখন কোনটা — guideline:

  • Tuple বাছুন যখন: heterogeneous data (record-like), function-এ multiple return, fixed dimensions, dict key।
  • List বাছুন যখন: homogeneous data (একই ধরনের items), iterate ও modify, length অজানা।

একটি বিখ্যাত Python idiom:

def divmod_(a, b):
    return a // b, a % b    # tuple return

quotient, remainder = divmod_(17, 5)    # unpacking

AI-তে concrete examples:

  • Tensor shape: (batch, channels, h, w) — চিরকাল 4। tuple।
  • Dataset items: (image, label) — fixed pair। tuple।
  • Loss history: per-epoch বাড়ছে। list।
  • Hyperparameter combinations: grid search-এ tuple — set-এর element বানানো যায়।

Trade-off-এর গভীর insight:

  • Mutable structures simple কিন্তু bug-prone (shared state)।
  • Immutable structures safe কিন্তু copy overhead।
  • আধুনিক language (Rust, Kotlin) — default immutable, opt-in mutation।
  • Python — mutable default, immutable opt-in (tuple, frozenset)।

মূল উপলব্ধি: "Mutability is a leak" — Hickey (Clojure)। Tuple ব্যবহারের অভ্যাস → কম bug, predictable code। AI-তে state-heavy কাজ → immutability discipline স্বর্ণমান।

প্র ০২ Dict-এর "O(1) lookup" কীভাবে সম্ভব? Hash table-এর জাদুর পেছনের কাহিনি কী? AI-তে এই concept কোথায় কাজে লাগে?

Hash table — কম্পিউটার বিজ্ঞানের সবচেয়ে গুরুত্বপূর্ণ data structure-গুলোর একটি। ১৯৫৩-এ IBM-এ Hans Peter Luhn আবিষ্কার করেন। আজ Python dict, Java HashMap, JS Object — সব এর উপর।

মূল ধারণা:

  • একটি বড় array (bucket)। যেমন: ৬৪ slots।
  • Key → hash function → integer (যেমন: "queen" → 7384295)।
  • Modulo — slot index: 7384295 % 64 = 39।
  • Slot 39-এ key-value জোড়া রাখা।
  • Lookup: একই hash + modulo → সেই slot → O(1)।

"গড়ে O(1)" — কেন গড়ে?

  • Collision: দু'টি key একই slot-এ। সমাধান: chaining বা open addressing।
  • Load factor > 0.75 — array দ্বিগুণ + পুরো rehash।
  • Worst case (সব collision) — O(n)। কিন্তু rare।
  • Good hash function = uniform distribution।

Hashable হতে কী লাগে?

  • Equality (__eq__) ও hash (__hash__)।
  • Lifetime-এ hash পরিবর্তন হতে পারবে না → immutable হতে হবে।
  • তাই — int, str, tuple, frozenset hashable। list, dict, set না।

AI-তে dict-এর critical applications:

  • Vocabulary: word → token_id mapping। ৫ লক্ষ word lookup → microseconds।
  • Cached embeddings: sentence → vector lookup।
  • Configuration: nested JSON-style hyperparameter।
  • Model state_dict: layer name → weight tensor (PyTorch)।
  • Memoization: expensive computation result cache।
  • Counter/frequency: word count for TF-IDF।

Python-এর dict-এর special powers:

  • Insertion-ordered (3.7+) — JSON serialization-এ predictable।
  • Compact dict (3.6+) — ~25% কম memory।
  • defaultdict, Counter, OrderedDict — collections module।
  • Dict comprehension: {k: v*2 for k, v in d.items()}

Hash collision attack — security:

  • ২০১১-এ — attacker known hash function-এ deliberate collisions দিয়ে web servers DoS করেছিল।
  • Python 3.3+ — hash randomization (PYTHONHASHSEED)।
  • প্রতি run-এ different hash → reproducibility-এ subtle issue।

মূল উপলব্ধি: Hash table = "search-এর math trick"। ১ লক্ষ items-এ search → ১ comparison। সঠিক data structure বাছাই = AI কোডের performance-এর ৫০%।

প্র ০৩ Python list বনাম NumPy array — দু'টোই sequence ধারণ করে। AI-তে কেন list-এর বদলে NumPy? Memory ও speed-এ কী পার্থক্য?

List ও NumPy array দেখতে similar — কিন্তু ভেতরে সম্পূর্ণ ভিন্ন data structure। AI কাজে এই পার্থক্য জানা না থাকলে — production-এ ১০০× ধীর কোড।

Python list — আসলে কী?

  • Heterogeneous: যেকোনো type-এর objects।
  • Pointer array — প্রতিটি element-এর address।
  • Dynamic sizing — পরে append চলে।
  • Memory: প্রতি element ~৫৬ bytes overhead।

NumPy array — আলাদা কোথায়?

  • Homogeneous: সব একই type (যেমন int32, float64)।
  • Contiguous memory — পাশাপাশি buffer।
  • C-level loops — vectorized operation।
  • Memory: float64 = ৮ bytes per element। শুধু।

Concrete comparison — ১০ লক্ষ float যোগ:

  • Python list: 10M × 56B = 560 MB। ~৫০০ ms।
  • NumPy array: 10M × 8B = 80 MB। ~৫ ms।
  • Memory ৭× কম, speed ১০০× বেশি।

কেন এই পার্থক্য?

  • Cache locality: contiguous memory → CPU cache friendly।
  • SIMD: CPU-এর Single Instruction Multiple Data — NumPy ব্যবহার করে।
  • No interpreter overhead: loop C-তে, Python virtual machine-এ যায় না।
  • BLAS/LAPACK: দশকের পর দশক optimized linear algebra library।

কখন list, কখন array?

  • List: mixed type, frequent append, small size, non-numerical।
  • Array: numerical computation, large data, math operations, AI/ML।

Modern hierarchy:

  • Python list → NumPy array → PyTorch tensor → GPU tensor।
  • প্রতি ধাপে — speed up + capability up।
  • Pandas DataFrame — NumPy-র উপর built, table semantics যোগ করে।

সাধারণ ভুল:

# খারাপ — Python loop
result = []
for x in big_list:
    result.append(x * 2)

# ভাল — vectorized
arr = np.array(big_list)
result = arr * 2          # ১০০× দ্রুত

মূল উপলব্ধি: Python list = data রাখার generic বাক্স। NumPy array = numerical computation-এর GPU-friendly বাক্স। AI = computation-heavy → array সবসময় বাছবেন। L09 থেকে NumPy বিস্তারিত।

প্র ০৪ JSON ও Python dict প্রায় same দেখা যায় — কেন? এই relationship AI-র কোন কাজে অপরিহার্য — API, dataset, configuration?

JSON ↔ dict — Python-এর secret weapon। এই isomorphism না বুঝলে — modern data engineering অসম্ভব।

JSON-এর জন্ম:

  • Douglas Crockford ২০০১-এ formalize করেন।
  • "JavaScript Object Notation" — কিন্তু ভাষা-নিরপেক্ষ।
  • XML-এর hierarchy + Python dict-এর সরলতা।

structural mapping:

  • JSON object {} ↔ Python dict
  • JSON array [] ↔ Python list
  • JSON string "" ↔ Python str
  • JSON number ↔ int/float
  • JSON true/false ↔ True/False
  • JSON null ↔ None

Python-এর built-in json module:

import json

# dict → JSON string
data = {"name": "ABCL", "scores": [85, 92]}
text = json.dumps(data, indent=2, ensure_ascii=False)

# JSON string → dict
parsed = json.loads(text)
print(parsed["name"])

# File operations
with open("data.json") as f:
    cfg = json.load(f)

AI-তে JSON-dict-এর প্রভাব:

  • API responses: OpenAI GPT-৪ API, HuggingFace inference — JSON returns। Python-এ instant dict।
  • Dataset annotations: COCO, ImageNet labels JSON-এ।
  • Configuration files: hyperparameters, model architecture.
  • Logging/metrics: Weights & Biases, MLflow।
  • NoSQL: MongoDB, Firestore — document = JSON = dict।

JSON-এর সীমা:

  • Comment নেই — তাই config-এ কেউ কেউ YAML/TOML বেছে।
  • Type limited — date, datetime নেই।
  • Tuple → list-এ rounds। দ্বিমুখী conversion lossy।
  • Trailing comma allowed না।

আধুনিক alternatives:

  • YAML: human-readable, comment-friendly। Kubernetes, Hugging Face model cards।
  • TOML: pyproject.toml — Python packaging।
  • Pydantic: JSON ↔ typed Python class। validation built-in।
  • Protobuf/MessagePack: binary, faster, ML serving।

Practical AI workflow:

# OpenAI API response
response = openai.chat.completions.create(...)
data = json.loads(response.choices[0].message.content)
# ↑ এখন pure Python dict — যেকোনো operation

মূল উপলব্ধি: JSON ↔ dict isomorphism — দু'টি জগতের মধ্যে অদৃশ্য সেতু। Network এ JSON, code-এ dict, file-এ JSON — কোনো friction নেই। Python AI-তে dominant হওয়ার অন্যতম কারণ এই natural fit।

অনুশীলন

  1. List slicing: nums = [10, 20, 30, 40, 50, 60, 70] — শেষ ৩টি, প্রথম ৩টি, এবং প্রতি দ্বিতীয়টি বের করুন।
    nums = [10, 20, 30, 40, 50, 60, 70]
    print(nums[-3:])    # [50, 60, 70]
    print(nums[:3])     # [10, 20, 30]
    print(nums[::2])    # [10, 30, 50, 70]
    print(nums[::-1])   # উল্টানো
  2. Word counter: একটি বাক্য দেওয়া আছে। প্রতিটি unique word কতবার আছে — dict দিয়ে count করুন।
    text = "AI is fun and AI is the future"
    words = text.lower().split()
    counter = {}
    for w in words:
        counter[w] = counter.get(w, 0) + 1
    print(counter)
    # {'ai': 2, 'is': 2, 'fun': 1, 'and': 1, 'the': 1, 'future': 1}
    
    # অথবা — collections.Counter
    from collections import Counter
    print(Counter(words))
  3. Set operations: Class A-তে students {"রহিম", "করিম", "জসিম"}; Class B-তে {"জসিম", "ফাতেমা", "রহিম"}। দু'ক্লাসেই কে আছে? শুধু A-তে কে?
    a = {"রহিম", "করিম", "জসিম"}
    b = {"জসিম", "ফাতেমা", "রহিম"}
    
    print("দু'ক্লাসেই:", a & b)    # {'রহিম', 'জসিম'}
    print("শুধু A-তে:", a - b)     # {'করিম'}
    print("একসাথে সব:", a | b)
    print("শুধু একটাতে:", a ^ b)   # symmetric diff

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

কোড রানার কাজ না করলে? ব্রাউজারে কাজ না করলে Google Colab ব্যবহার করুন।
পূর্ববর্তী পাঠ
পাঠ ০২ · Variable, ডেটা টাইপ ও অপারেটর