Python syntax, data types, control flow
Why Python for AI/ML?
Python dominates AI/ML for three reasons:
- Readable syntax → faster protyping and debugging
- Rich ecosystem → NumPy, Pandas, Scikit-learn, PyTorch, TensorFlow
- Dynamic typing → rapid experimentation (trade computational speed for development speed)
The dynamic typing means Python checks types at runtime, not compile-time. This flexibility is why you can quickly test ML hypotheses, but also why you need to understand types deeply to avoid subtle bugs.
Python Data Types: The Building Blocks
Why These Types Matter in ML
Integers and Floats: Represent features, labels, hyperparameters. Float precision affects numerical stability in gradient descent.
Lists vs Tuples: Lists for mutable data (e.g., collecting predictions), tuples for immutable configs (e.g., input_shape=(28, 28, 1)).
Dictionaries: Store model hyperparameters, config files, feature mappings. O(1) average lookup time.
None: Represent missing data before imputation, uninitialized model weights.
Type Conversion andercion
Python has explicit type conversion (no automatic coercion between numeric types in operations that could lose precision):
# Explicit conversions
x = int(3.7) # 3 (truncates, doesn't round)
y = float("2.5") # 2.5
z = str(42) # "42"
# Mixed arithmetic promotes to most general type
result = 5 + 2.0 # 7.0 (int + float → float)Why explicit? Prevents silent precision loss bugs. In ML, accidentally converting float weights to int would destroy model performance.
Python Syntax: Indentation as Grammar
# Correct indentation
if accuracy > 0.95:
print("Model converged")
save_checkpoint() # Part of if-block
print("Training complete") # Outside if-block
# WRONG: Inconsistent indentation causes IndentationError
if accuracy > 0.95:
print("Model converged")
save_checkpoint() # ERROR: unexpected indentWhy this design? Forces readable code. In ML research code shared across teams, consistent structure reduces cognitive load.
Variables and Assignment
Python uses reference semantics:
# Assignment creates a reference, not a copy
weights_original = [0.5, 0.3, 0.8]
weights_backup = weights_original # Both point to SAME list
weights_backup[0] = 0.9 # Modifies the original too!
print(weights_original) # [0.9, 0.3, 0.8]
# Correct: explicit copy
import copy
weights_backup = copy.deepcopy(weights_original)Why this matters in ML: Neural network layers often share weight references. Modifying one reference affects all unless you explicitly copy.
learning_rate = 0.01 # Global
def train_model():
learning_rate = 0.001 # Local (shadows global)
def update_weights():
# Uses enclosing function's learning_rate (0.001)
print(f"LR: {learning_rate}")
update_weights()
train_model() # Prints "LR: 0.001"Control Flow: Directing Computation
Conditional Statements
Truthiness in Python: Objects have inherent boolean values. Empty containers ([], {}, "), 0, `None are falsy. All others are truthy.
# Checking if list is non-empty (Pythonic)
predictions = [0.9, 0.3, 0.7]
if predictions: # Truthy because list is non-empty
avg = sum(predictions) / len(predictions)Loops: For and While
List Comprehensions: Concise syntax for creating lists from iterables.
# Standard loop
squared = []
for x in range(10):
squared.append(x ** 2)
# List comprehension (Pythonic)
squared = [x ** 2 for x in range(10)]
# With condition (filter)
even_squared = [x ** 2 for x in range(10) if x % 2 == 0]
# [0, 4, 16, 36, 64]
# Why use this? More readable, often faster (optimized C implementation).
# Common in data preprocessing: [preprocess(x) for x in dataset]Loop Control: Break and Continue
break: Immediately exit innermost loopcontinue: Skip remaining loop body, proceed to next iteration
# Skip corrupted data samples
for i, sample in enumerate(dataset):
if is_corrupted(sample):
print(f"Skipping sample {i}")
continue # Skip to next iteration
if i >= max_samples:
break # Exit loop entirely
process(sample)Functions: Encapsulation and Reusability
Argument Passing
Python uses pass-by-object-reference:
- Immutable objects (int, float, str, tuple): Behave like pass-by-value (can't modify)
- Mutable objects (list, dict, set): Modifications inside function affect original
def modify_list(lst):
lst.append(4) # Modifies original list
def modify_int(x):
x += 10 # Creates new local int, doesn't affect original
my_list = [1, 2, 3]
modify_list(my_list)
print(my_list) # [1, 2, 3, 4]—modified!
my_int = 5
modify_int(my_int)
print(my_int) # 5—unchangedWhy this matters in ML: Passing large arrays/tensors to functions doesn't copy data (efficient), but unexpected modifications can cause bugs.
*args and **kwargs
def train_model(model, data, *args, **kwargs):
"""
*args: Positional arguments as tuple
**kwargs: Keyword arguments as dict
"""
epochs = kwargs.get('epochs', 100) # Default 100
lr = kwargs.get('learning_rate', 0.01)
print(f"Extra args: {args}")
print(f"Extra kwargs: {kwargs}")
# Call with various arguments
train_model(my_model, my_data, "extra", "values",
epochs=50, learning_rate=0.001, batch_size=32)
# args = ("extra", "values")
# kwargs = {'epochs': 50, 'learning_rate': 0.001, 'batch_size': 32}Use case: Creating flexible APIs (like Keras model.fit() which accepts many optional hyperparameters).
Exception Handling
EAFP vs LBYL: Python favors "Easier to Ask Forgiveness than Permission" (try-except) over "Look Before You Leap" (if checks). Exceptions are not expensive in Python when uncomon.
Comprehensions Beyond Lists
Dictionary Comprehension:
# Create feature name to index mapping
feature_names = ['age', 'income', 'score']
feature_to_idx = {name: i for i, name in enumerate(feature_names)}
# {'age': 0, 'income': 1, 'score': 2}Set Comprehension:
# Unique labels in dataset
labels = [0, 1, 0, 2, 1, 2]
unique_labels = {label for label in labels}
# {0, 1, 2}Generator Expression (memory-efficient, lazy evaluation):
# Process large dataset without loading all into memory
data_generator = (preprocess(x) for x in huge_dataset)
# Values computed on-demand during iteration
for item in data_generator:
train_on(item)Why generators in ML? When dataset doesn't fit in RAM. TensorFlow's tf.data and PyTorch's DataLoader use this principle.
Recall Explain to a 12-year-old
Imagine you're teaching a robot to cook. Python is the instruction booklet language.
Data types are like ingredient categories: numbers (how many eggs), text (recipe name), lists (shopping list you can change), tuples (ingredient ratios that never change).
Control flow is the recipe steps: "IF oven is hot THEN put cake in, ELSE wait." Or "FOR each of 12 cupcakes, add frosting."
Functions are sub-recipes: Instead of writing "mix flour, sugar, butter" every time, you create a "make_dough()" recipe you can reuse.
Indentation (those spaces before lines) shows which instructions go together—like how recipe steps under "Baking" are indented under that heading.
In ML, you're teaching computers to learn patterns. Python is how you give those teaching instructions clearly. Just like recipes need exact measurements, ML code needs exact data types. Just like you might say "keep mixing UNTIL smooth," ML uses WHILE loops to train UNTIL the model is good enough.
Connections NumPy arrays and vectorization - Built on Python lists but optimized for numerical computation
- Pandas DataFrames - Uses Python dicts internally, adds ML-focused data manipulation
- Python functions and lambda - Function definition extends to anonymous functions
- Object-oriented programming in Python - Classes build on function and scope concepts
- TensorFlow and PyTorch basics - ML frameworks use Python control flow for training loops
- Exception handling in data pipelines - Try-except patterns for robust ML systems
- Python iterators and generators - Extends loop concepts for memory efficiency
Practice Problems
- Write a function that takes a list of model predictions and returns accuracy, precision, and recall.
- Implement early stopping with a while loop that tracks validation loss.
- Create a dict comprehension that maps layer names to parameter counts in a neural network.
- Debug this code: Why does modifying
layer_configinside a function change the original?

#flashcards/ai-ml
What is Python's LEGB rule for variable resolution? :: Local → Enclosing → Global → Built-in. Python searches these scopes in order to resolve variable names.
Why does Python use indentation for code blocks instead of braces?
What's the difference between = and == in Python?
= is assignment (creates/updates variable reference). == is comparison (tests equality, returns boolean).What happens when you do y = x where x is a list?
copy.deepcopy() for independent copy.When should you use a while loop vs a for loop in ML?
What does range(0, 100, 32) produce? :: [0, 32, 64, 96]. Start at 0, step by 32, stop before 100. Useful for batch indices.
Why is int vs float important in ML? :: Float precision affects numerical stability in gradient descent. Integer for discrete counts (epochs, batch indices). Mixing incorrectly causes shape errors or precision loss.
What's the difference between break and continue?
break exits the entire loop immediately. continue skips remaining statements in current iteration and jumps to next iteration.What does if predictions: check?
Why use list comprehensions over for loops?
[preprocess(x) for x in dataset].What's the output of [x**2 for x in range(5) if x % 2 == 0]?
What's the difference between *args and **kwargs?
*args captures positional arguments as tuple. **kwargs captures keyword arguments as dict. Used for flexible function APIs.Why use try-except instead of if-checks in Python?
What does finally do in exception handling?
Why are generators memory-efficient?
What's the difference between list and tuple?
How do you convert float3.7 to int in Python?
int(3.7) returns 3 (truncates toward zero, doesn't round). Use round(3.7) then int() for rounding.What's the result of 5 + 2.0 in Python?
Why does dataset_size / batch_size return float in Python3?
/ always performs true division (returns float). Use // for floor division (returns int), needed for discrete step counts.What happens if you modify a list passed to a function?
Concept Map
Hinglish (regional understanding)
Intuition Hinglish mein samjho
Hinglish (regional understanding)
Intuition Hinglish mein samjho
Dekho, Python ko AI/ML ki "duniya ki common language" isliye kehte hain kyun ki ye ek unique balance deta hai — code padhne mein aasan (human readable) hota hai, aur phir bhi bahut powerful hai. Jaise kisi bhi bhasha ko bolne ke liye pehle uski grammar seekhni padti hai, waise hi ML ke bade concepts express karne ke liye tumhe Python ka syntax, data types, aur control flow samajhna zaroori hai. Har TensorFlow model, har NumPy array ka kaam, har data pipeline — sab yahin se, in fundamentals se, shuru hota hai. Isliye ye foundation strong hona bahut matter karta hai.
Ab data types ki baat karein — ye tumhare building blocks hain. int, float, list, tuple, dict, None — ye sab ML mein alag-alag kaam aate hain. Jaise floats tumhare features aur weights represent karte hain, aur unki precision gradient descent ki numerical stability pe asar daalti hai. Ek important cheez: Python "dynamic typing" use karta hai, matlab type runtime pe check hoti hai, compile-time pe nahi. Ye flexibility experiments jaldi karne mein help karti hai, lekin isi wajah se tumhe types deeply samajhna padta hai warna chhote-chhote subtle bugs aa jaate hain. Ek classic example — training steps nikalte waqt / (normal division) float deta hai jaise 31.25, par tumhe // (floor division) chahiye kyunki tum 0.25 batch update nahi kar sakte, steps hamesha integer hone chahiye.
Aur ek cheez yaad rakho — Python "strong typing" bhi rakhta hai, yani woh apne aap incompatible types convert nahi karega. Jaise "Epoch " + 5 seedha error dega; tumhe khud str(5) likhna padega. Ye design jaan-boojh kar hai taaki silent precision-loss wale bugs na ho — socho agar tumhare float weights galti se int mein convert ho jaayein, toh poora model performance barbaad ho jaayega. Iske alawa Python indentation (spaces) se code blocks banata hai, braces se nahi — aur ye syntactically enforced hai, sirf style nahi. Ye sab basics chhoti lagti hain, par inhe theek se samajhna hi tumhe aage confidently ML code likhne aur debug karne layak banata hai.