🐍 The Ultimate Python Review Guide
All 18 Sections · Competition Edition
Section 1 · Basics
Key Terms: interpreted, dynamically typed, syntax, statement, expression
Summary
● Python is high-level, interpreted, and dynamically typed — variable types are set at
runtime, not declared.
● Code blocks are defined by indentation (4 spaces). No curly braces. Wrong indentation
= IndentationError.
● PEP 8: use 4 spaces per level, never mix tabs and spaces.
● Run files with python [Link] or python3 [Link].
python
Python
print("Hello, World!") # basic output
print("a", "b", sep="-", end="!") # sep/end options
# single-line comment
x = 5 # inline comment
Section 2 · Data Types & Type Casting
Key Terms: int, float, bool, str, None, casting, implicit/explicit conversion
Built-in Types
Type Example Notes
int 42, 1_000 arbitrary precision
float 3.14, 64-bit
2.0e8
bool True, subclass of int (True=1,
False False=0)
str 'hi', immutable, Unicode
"hi"
None None absence of value
compl 3+4j real + imaginary
ex
Summary
● Use type(x) to inspect type at runtime.
● Implicit casting: int + float → float (automatic).
● Explicit casting: int(), float(), str(), bool().
● int(3.9) → 3 (truncates, does NOT round). Use round() to round.
● Falsy values: 0, 0.0, '', None, [], {}, ()
python
Python
# Variables
x = 10
a, b, c = 1, 2, 3 # multiple assignment
a, b = b, a # swap (no temp variable needed)
# Casting
print(int("42")) # 42
print(float(7)) # 7.0
print(bool("")) # False
print(bool("hi")) # True
# Strings
s = "Hello, Python!"
print(s[0]) # H
print(s[-1]) # !
print(s[0:5]) # Hello
print(s[::-1]) # reversed
print(len(s)) # 14
print([Link]()) # HELLO, PYTHON!
print([Link](", ")) # ['Hello', 'Python!']
Section 3 · Loops
Key Terms: iteration, iterable, iterator, for, while, range, break, continue, pass
Summary
● for loop is a for-each — iterates over any iterable. No C-style for(int i=0;...).
● range(stop) → 0 to stop-1. range(start, stop, step).
● while — use when you don't know iteration count ahead of time.
● break exits the loop. continue skips to the next iteration.
● for/while ... else — the else block runs only if the loop finished without break.
python
Python
# for loop
for i in range(1, 6): # 1 2 3 4 5
print(i, end=" ")
# enumerate — index + value
fruits = ["apple", "banana", "cherry"]
for i, fruit in enumerate(fruits):
print(i, fruit)
# zip — parallel iteration
for name, score in zip(["Alice","Bob"], [95, 82]):
print(f"{name}: {score}")
# while
count = 0
while count < 5:
count += 1
# break / continue
for i in range(10):
if i == 5: break # stops at 5
for i in range(10):
if i % 2 == 0: continue # skips evens
# for...else (search pattern)
for n in [1, 3, 5]:
if n == 7:
print("Found!"); break
else:
print("Not found") # runs — no break hit
Section 4 · Nested Structures & Scope
Key Terms: nested loops, LEGB rule, global, nonlocal
Summary
● LEGB: Python looks up names in order — Local → Enclosing → Global → Built-in.
● global keyword: lets a function modify a global variable.
● nonlocal keyword: lets an inner function modify a variable in its enclosing (but not
global) scope.
● Avoid overusing global/nonlocal — prefer passing arguments and returning values.
python
Python
# Nested loop — multiplication table
for i in range(1, 4):
for j in range(1, 4):
print(i * j, end="\t")
print()
# LEGB example
x = "global"
def outer():
x = "enclosing"
def inner():
x = "local"
print(x) # local
inner()
print(x) # enclosing
outer()
print(x) # global
# global keyword
count = 0
def increment():
global count
count += 1
# nonlocal keyword
def make_counter():
n = 0
def inc():
nonlocal n
n += 1
return n
return inc
Section 5 · Operations
Key Terms: arithmetic, comparison, logical, bitwise, augmented assignment, operator
precedence
Arithmetic Operators
Op Meaning Example
+- add, sub, mul 5+3=8
*
/ true division (always float) 7/2=3.5
// floor division 7//2=3
% modulus/remainder 7%2=1
** exponentiation 2**10=10
24
Summary
● Python allows chained comparisons: 18 <= age <= 65
● and/or short-circuit: and stops at first False, or stops at first True.
● Augmented assignment: x += 3, x //= 5, x **= 2, etc.
● Precedence (high→low): ** → unary → * / // % → + - → comparisons → not →
and → or
python
Python
print(10 // 3) # 3
print(-7 // 2) # -4 (floor toward -infinity!)
print(10 % 3) # 1
print(15 % 2 == 0) # False — odd number check
# math library
import math
print([Link](144)) # 12.0
print([Link](-3.2)) # -4
print([Link](-3.2)) # -3
print([Link](5)) # 120
print([Link](48, 18)) # 6
print([Link]) # 3.14159...
Section 6 · Methods & Parameters
Key Terms: function, parameter, argument, return value, default value, *args, **kwargs,
lambda, docstring
Summary
● A parameter is the placeholder in the definition. An argument is the value passed in the
call.
● Without return, a function returns None.
● Python does not support traditional overloading — use default parameters,
*args/**kwargs, or isinstance().
● Lambda: anonymous one-liner function. Often used with sorted(), map(),
filter().
● Single Responsibility Principle: each function should do one thing.
python
Python
# Basic function
def greet(name):
return f"Hello, {name}!"
# Default parameter
def power(base, exp=2):
return base ** exp
print(power(3)) # 9
print(power(3, 3)) # 27
# Multiple return values (returns a tuple)
def min_max(nums):
return min(nums), max(nums)
lo, hi = min_max([3,1,9,5])
# *args (arbitrary positional → tuple)
def total(*args):
return sum(args)
print(total(1, 2, 3, 4)) # 10
# **kwargs (arbitrary keyword → dict)
def display(**kwargs):
for k, v in [Link]():
print(f"{k} = {v}")
# Lambda
square = lambda x: x ** 2
nums = [3,1,4,1,5,9]
print(sorted(nums, key=lambda x: -x)) # descending
# Simulating overloading
def area(length, width=None):
return length**2 if width is None else length * width
Section 7 · Input
Key Terms: input(), token, parsing, map(), validation
Summary
● input() always returns a string — cast as needed.
● A token is a whitespace-separated unit of data.
● map(function, iterable) applies a function to every element — combine with
split() for multi-token input.
● Always validate user input before using it.
python
Python
name = input("Name: ") # string
age = int(input("Age: ")) # cast to int
# Two tokens on one line
a, b = input("Two numbers: ").split()
a, b = int(a), int(b)
# map() for multiple values
x, y = map(float, input("Two floats: ").split())
# Multiple integers at once
numbers = list(map(int, input().split()))
# Input validation with try/except
while True:
try:
age = int(input("Age (0-120): "))
if 0 <= age <= 120:
break
else:
print("Out of range.")
except ValueError:
print("Enter a whole number.")
Section 8 · Conditionals
Key Terms: if, elif, else, ternary, match-case, truthy/falsy
Summary
● Only the first true branch executes — Python checks top to bottom.
● Ternary: value_if_true if condition else value_if_false
● match/case (Python 3.10+) — like switch/case but more powerful.
● Use is / is not to check for None, not ==.
python
Python
# if / elif / else
score = 85
if score >= 90: grade = "A"
elif score >= 80: grade = "B"
elif score >= 70: grade = "C"
else: grade = "F"
# Ternary
status = "adult" if age >= 18 else "minor"
# match / case (3.10+)
match command:
case "quit": print("Quitting...")
case "help": print("Help...")
case _: print("Unknown") # default wildcard
# Common patterns
if value is None: ...
if "alice" in ["alice", "bob"]: ...
if not name: ... # empty string is falsy
if items: ... # non-empty list is truthy
Section 9 · F-strings & Print Formatting
Key Terms: f-string, format spec, width, precision, alignment
Summary
● Prefix with f or F. Embed any expression in {}.
● Format spec syntax: {value:[[fill]align][width][.precision][type]}
● Python 3.8+: {x=} prints both name and value (great for debugging).
● Use f-strings for all new code — faster and more readable than % or .format().
python
Python
name, pi = "Alice", 3.14159
print(f"Hello, {name}!") # Hello, Alice!
print(f"{pi:.2f}") # 3.14
print(f"{pi:10.2f}") # ' 3.14' (width 10)
print(f"{pi:<10.2f}") # '3.14 ' (left)
print(f"{pi:010.2f}") # 0000003.14 (zero-pad)
print(f"{255:b}") # 11111111 (binary)
print(f"{255:x}") # ff (hex)
print(f"{1234567:,}") # 1,234,567
x = 42
print(f"{x=}") # x=42 (debug)
s = "hello"
print(f"{s:*^10}") # **hello*** (centered, fill
*)
Section 10 · Random
Key Terms: random, seed, secrets, weighted choices, Gaussian distribution
Summary
● Always import random. Use [Link](n) for reproducibility.
● For security-sensitive use (passwords, tokens) — use secrets, not random.
python
Python
import random
[Link]() # float in [0.0, 1.0)
[Link](1.0, 10.0) # float in [a, b]
[Link](1, 6) # int in [a, b] inclusive
[Link](["r","g","b"]) # one random element
[Link](["r","g","b"], k=5) # k with replacement
[Link](["r","g","b"], k=2) # k without replacement
deck = list(range(1, 53))
[Link](deck) # shuffle IN PLACE
[Link](42) # reproducible sequence
# Weighted choices
[Link](["win","lose"], weights=[1,3], k=10)
# Gaussian (normal) distribution
h = [Link](170, 10) # mean=170, std=10
# Secure random (for passwords/tokens)
import secrets
[Link](100)
secrets.token_urlsafe(32)
Section 11 · Algorithm Principles
Key Terms: Boolean zen, assertions, fencepost, lookahead, DeMorgan's Laws, invariant,
precondition, postcondition
Summary
● Boolean zen: don't compare booleans to True/False — the boolean IS the condition.
● Assertion: assert expr, msg — raises AssertionError if expr is False. For
debugging only, not user validation.
● Fencepost problem: off-by-one errors — use [Link]() to avoid trailing separators.
● Lookahead: inspect nums[i+1] before consuming nums[i].
● DeMorgan's Laws: not (A and B) ≡ (not A) or (not B) and not (A or B) ≡
(not A) and (not B)
python
Python
# Boolean zen
is_valid = True
if is_valid: ... # GOOD
if is_valid == True: ... # BAD
def is_even(n):
return n % 2 == 0 # GOOD (not if/else with True/False)
# Assertion
def divide(a, b):
assert b != 0, f"b={b}"
return a / b
# Fencepost — trailing comma fix
fruits = ["apple","banana","cherry"]
print(", ".join(fruits)) # apple, banana, cherry
# Lookahead — detect consecutive duplicates
nums = [1,2,2,3,4,4]
for i in range(len(nums)-1):
if nums[i] == nums[i+1]:
print(f"Duplicate at {i}: {nums[i]}")
# DeMorgan
# not (x > 5 and y < 10) ≡ x <= 5 or y >= 10
Section 12 · File Processing
Key Terms: file handle, open(), mode, with block, readline, readlines, CSV
File Modes
Mode Meaning
'r' Read (default). File must exist.
'w' Write. Creates or overwrites.
'a' Append. Creates or adds to
end.
'x' Exclusive create. Fails if exists.
Summary
● Always use with open(...) as f: — auto-closes even on errors.
● Iterate directly over a file object — most memory-efficient method.
● [Link]() removes trailing \n.
python
Python
# Reading
with open("[Link]") as f:
for line in f:
print([Link]())
# Writing
with open("[Link]", "w") as f:
[Link]("Hello\n")
print("From print", file=f) # redirect print to file
# Append
with open("[Link]", "a") as f:
[Link]("New entry\n")
# Token-based
with open("[Link]") as f:
for line in f:
for token in [Link]():
print(int(token) * 2)
# CSV
import csv
with open("[Link]") as f:
reader = [Link](f)
next(reader) # skip header
for row in reader:
print(row)
with open("[Link]", "w", newline="") as f:
writer = [Link](f)
[Link](["Name","Score"])
[Link]([["Alice",95],["Bob",82]])
Section 13 · Arrays (Lists as Arrays)
Key Terms: dynamic array, index, O(1) access, value vs reference semantics, shallow/deep
copy, 2-D array
Summary
● Python lists are dynamic arrays — O(1) index access, amortised O(1) append.
● Reference semantics: assigning a list to another variable makes both point to the same
object. Modifying one affects the other.
● To truly copy: use .copy(), [:], list(x), or [Link](x) for nested
structures.
● [[0]*cols]*rows is wrong for 2-D — all rows share the same list. Use a
comprehension instead.
python
Python
nums = [10, 20, 30, 40, 50]
print(nums[0], nums[-1]) # 10 50
print(nums[1:4]) # [20, 30, 40]
[Link](60)
[Link](0, 5)
[Link](30)
popped = [Link]() # removes last
[Link]()
[Link]()
# Reference semantics — IMPORTANT
x = [1,2,3]
y = x # y points to SAME list
y[0] = 99
print(x) # [99,2,3] — x is also changed!
# Proper copy
z = [Link]() # shallow copy — now independent
# 2-D array (CORRECT way)
rows, cols = 3, 4
matrix = [[0]*cols for _ in range(rows)]
# List comprehensions
squares = [x**2 for x in range(10)]
evens = [x for x in range(20) if x % 2 == 0]
flat = [val for row in matrix for val in row] # flatten
# Useful builtins
print(min(nums), max(nums), sum(nums))
print(any(x > 8 for x in nums)) # True if any match
print(all(x > 0 for x in nums)) # True if all match
Section 14 · Lists, Tuples & Dictionaries
Key Terms: tuple (immutable), dictionary (hash map), set, defaultdict, namedtuple,
comprehension
Summary
● Tuple: ordered, immutable. Faster than list, hashable (can be dict key or set element).
● Dictionary: key→value, O(1) average lookup. Keys must be unique.
● Set: unordered, unique elements. O(1) membership test. set() for empty — {} makes
a dict!
● Use .get(key, default) to avoid KeyError.
python
Python
# Tuple
point = (3, 4)
x, y = point # unpack
single = (42,) # trailing comma required for
single-element
# Named tuple
from collections import namedtuple
Point = namedtuple("Point", ["x","y"])
p = Point(3,4); print(p.x, p.y)
# Dictionary
student = {"name":"Alice","age":20}
print(student["name"]) # Alice
print([Link]("major","Undeclared")) # safe access
student["age"] = 21 # update
del student["age"] # delete
for k, v in [Link](): print(k, v)
# defaultdict
from collections import defaultdict
word_count = defaultdict(int)
for w in "the cat the".split():
word_count[w] += 1
# Dict comprehension
squares = {x: x**2 for x in range(6)}
inverted = {v: k for k, v in [Link]()}
# Set
a = {1,2,3,4}; b = {3,4,5,6}
print(a | b) # union {1,2,3,4,5,6}
print(a & b) # intersection {3,4}
print(a - b) # difference {1,2}
print(a ^ b) # symmetric {1,2,5,6}
# Remove duplicates
unique = sorted(set([1,2,2,3,3,3]))
Section 15 · Objects & Classes
Key Terms: class, object, instance, attribute, method, self, __init__, dunder methods,
static/class/instance
Summary
● self refers to the current instance — required as first parameter of every instance
method.
● __init__ is the constructor — called when the class is instantiated.
● Instance variable: unique per object (self.x). Class variable: shared across all
instances.
● Dunder (magic) methods: __str__, __repr__, __add__, __eq__, __len__, etc.
python
Python
class Dog:
species = "Canis lupus" # class variable
def __init__(self, name, age):
[Link] = name # instance variable
[Link] = age
def bark(self):
return f"{[Link]}: Woof!"
def __str__(self):
return f"Dog({[Link]}, {[Link]})"
d = Dog("Rex", 3)
print([Link]()) # Rex: Woof!
print([Link]) # Canis lupus
# Static vs class methods
class Counter:
total = 0
def __init__(self):
[Link] += 1
@classmethod
def get_total(cls): # operates on class
return [Link]
@staticmethod
def description(): # utility, no self/cls
return "A counter"
# Dunder methods
class Vector:
def __init__(self, x, y): self.x, self.y = x, y
def __str__(self): return f"({self.x},{self.y})"
def __add__(self, o): return Vector(self.x+o.x, self.y+o.y)
def __eq__(self, o): return self.x==o.x and self.y==o.y
Section 16 · The Big 4 (OOP Pillars)
Key Terms: encapsulation, inheritance, polymorphism, abstraction, super(), ABC,
@abstractmethod, duck typing
1. Encapsulation — bundle data + restrict access
python
Python
class BankAccount:
def __init__(self, owner, balance=0):
[Link] = owner
self._balance = balance # _ = convention for
"private"
@property
def balance(self): return self._balance
@[Link]
def balance(self, amount):
if amount < 0: raise ValueError("Cannot be negative")
self._balance = amount
def deposit(self, amount):
self._balance += amount
2. Inheritance — reuse via is-a relationship
python
Python
class Animal:
def __init__(self, name): [Link] = name
def eat(self): print(f"{[Link]} eating.")
def speak(self): raise NotImplementedError
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name) # call parent __init__
[Link] = breed
def speak(self): return "Woof!"
print(isinstance(Dog("Rex","Lab"), Animal)) # True
3. Polymorphism — same interface, different behavior
python
Python
animals = [Dog("Rex","Lab"), Cat("Luna")]
for a in animals:
print([Link]()) # calls the RIGHT version automatically
# Duck typing — no inheritance needed
class Duck:
def speak(self): return "Quack!"
class Robot:
def speak(self): return "Beep!"
for t in [Duck(), Robot()]:
print([Link]()) # works because both have speak()
4. Abstraction — hide complexity, expose interface
python
Python
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self): pass # subclasses MUST implement
@abstractmethod
def perimeter(self): pass
class Circle(Shape):
def __init__(self, r): self.r = r
def area(self): return 3.14159 * self.r**2
def perimeter(self): return 2 * 3.14159 * self.r
# Shape() ← TypeError: can't instantiate abstract class
Section 17 · Sorting & Searching
Key Terms: Big O, linear search, binary search, selection sort, insertion sort, merge sort,
Timsort
Big O Cheat Sheet
Complexity Name Example
O(1) Constant dict lookup, list index
O(log n) Logarithmic binary search
O(n) Linear linear search
O(n log n) Linearithmic merge sort, Timsort
O(n²) Quadratic bubble/selection sort
Summary
● Python's built-in sort is Timsort — O(n log n) worst, O(n) best (nearly-sorted data).
● sorted() returns a new list. .sort() sorts in-place.
● Binary search requires a sorted list. Cuts search space in half each step.
python
Python
# Built-in sort
nums = [5,2,8,1,9]
print(sorted(nums)) # new list
[Link](reverse=True) # in-place
students = [("Alice",95),("Bob",82)]
[Link](key=lambda s: s[1]) # sort by score
# Linear Search — O(n)
def linear_search(lst, target):
for i, v in enumerate(lst):
if v == target: return i
return -1
# Binary Search — O(log n), list must be sorted
def binary_search(lst, target):
low, high = 0, len(lst)-1
while low <= high:
mid = (low+high)//2
if lst[mid] == target: return mid
elif lst[mid] < target: low = mid+1
else: high = mid-1
return -1
# Selection Sort — O(n²)
def selection_sort(lst):
for i in range(len(lst)):
min_i = i
for j in range(i+1, len(lst)):
if lst[j] < lst[min_i]: min_i = j
lst[i], lst[min_i] = lst[min_i], lst[i]
# Merge Sort — O(n log n)
def merge_sort(lst):
if len(lst) <= 1: return lst
mid = len(lst)//2
left = merge_sort(lst[:mid])
right = merge_sort(lst[mid:])
result, i, j = [], 0, 0
while i < len(left) and j < len(right):
if left[i] <= right[j]: [Link](left[i]); i+=1
else: [Link](right[j]); j+=1
return result + left[i:] + right[j:]
Section 18 · Recursion
Key Terms: base case, recursive case, call stack, memoization, lru_cache, stack limit
Summary
● Every recursive function needs: base case (stops recursion) + recursive case (smaller
sub-problem) + progress toward base case.
● Python's default stack limit is ~1000 frames.
● Memoization (@lru_cache) caches results — turns O(2ⁿ) Fibonacci into O(n).
● When to use recursion: tree/graph traversal, divide & conquer, backtracking.
python
Python
# Factorial — O(n)
def factorial(n):
if n == 0: return 1 # base case
return n * factorial(n-1) # recursive case
# Fibonacci — naive O(2^n), memoized O(n)
from functools import lru_cache
@lru_cache(maxsize=None)
def fib(n):
if n <= 1: return n
return fib(n-1) + fib(n-2)
print([fib(i) for i in range(10)]) # [0,1,1,2,3,5,8,13,21,34]
# Recursive sum
def r_sum(lst):
if not lst: return 0
return lst[0] + r_sum(lst[1:])
# Fast power — O(log n)
def fast_power(base, exp):
if exp == 0: return 1
if exp % 2 == 0:
half = fast_power(base, exp//2)
return half * half
return base * fast_power(base, exp-1)
# Binary search (recursive)
def bin_search(lst, target, lo, hi):
if lo > hi: return -1
mid = (lo+hi)//2
if lst[mid] == target: return mid
elif lst[mid] < target: return bin_search(lst, target, mid+1,
hi)
else: return bin_search(lst, target, lo, mid-1)
# Tower of Hanoi
def hanoi(n, src, dst, aux):
if n == 1:
print(f"Move disk 1: {src} → {dst}"); return
hanoi(n-1, src, aux, dst)
print(f"Move disk {n}: {src} → {dst}")
hanoi(n-1, aux, dst, src)
# Requires 2^n - 1 moves
Recursion vs Iteration — Quick Reference
Recursion Iteration
Readability Mirrors math definition More explicit
Performance Slower (call overhead) Faster
Stack limit ~1000 frames in Python No limit
Best for Trees, divide & conquer, backtracking Most other loops
Fix slow recursion @lru_cache memoization —