List, Tuple ও Dictionary
এই পাঠে যা শিখবেন
- 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-আলাদা মান।
# 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]) # উল্টো
scores[0] প্রথম। ঋণাত্মক index শেষ থেকে। Slicing start:stop stop exclusive — গুরুত্বপূর্ণ মনে রাখা।
২ · List পরিবর্তন
fruits = ["আম", "জাম"]
fruits.append("কাঁঠাল") # শেষে যোগ
fruits.insert(0, "লিচু") # নির্দিষ্ট স্থানে
print(fruits) # ['লিচু', 'আম', 'জাম', 'কাঁঠাল']
fruits.remove("জাম") # মান দিয়ে মুছে
print(fruits)
last = fruits.pop() # শেষেরটা ফেরত ও মুছে
print(f"মোছা: {last}, অবশিষ্ট: {fruits}")
fruits.sort() # বর্ণানুক্রমিক
print(fruits)
scores.sort() পুরনো scores-কে বদলে দেয়। Original রাখতে চাইলে sorted(scores) — নতুন list ফেরত।
৩ · Tuple — অপরিবর্তনীয় তালিকা
Tuple দেখতে list-এর মতো — কিন্তু বন্ধনী (), এবং immutableImmutableএকবার তৈরির পরে পরিবর্তন করা যায় না। int, str, tuple, frozenset — Python-এর immutable type। dict-এর key, set-এর element হতে পারে।। তৈরির পর পরিবর্তন করা যায় না।
# 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)
৪ · Dictionary — key থেকে value
ফোনবুকের মতো — নাম দিয়ে নম্বর খোঁজা। {key: value} — Python-এর সবচেয়ে শক্তিশালী collection।
# 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 সদস্য
# 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
৬ · 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-এর রাজা।
৭ · 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।
অনুশীলন
-
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]) # উল্টানো -
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)) -
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-এ আপনার পরবর্তী পদক্ষেপ
- পাঠ ০৪ · if/else ও loop পরবর্তী পাঠ এই collections-গুলোর উপর iterate করার সব পদ্ধতি।
- পাঠ ০২ · Variable, ডেটা টাইপ ও অপারেটর আগের পাঠ
- পাঠ ০৬ · List comprehension ও iterator সম্পর্কিত List/dict-এর Pythonic transformation।
- সব AI Courses দেখুন ABCL TECH