Essential Python syntax, data structures, comprehensions, and common patterns for quick reference
Basic Syntax
Variables
Python uses dynamic typing - no type declaration needed
# Variables (dynamically typed)
x = 5
name = "John"
is_active = True Variables
Python prioritizes developer productivity and readability. Dynamic typing means less boilerplate code and faster prototyping, though you can add type hints for larger projects.
Use descriptive variable names (snake_case), and consider type hints for function signatures in production code.
Variables can change type unexpectedly. Use isinstance() to check types when needed.
String Formatting
f-strings (Python 3.6+) or str.format() method
name = "Alice"
age = 25
print(f"Hello, {name}. You are {age} years old")
print("Hello, {}. You are {} years old".format(name, age)) String Formatting
f-strings are preferred for Python 3.6+. They're more readable, faster, and allow expressions inside braces like {age + 1}.
Use .format() when you need to reuse a template string or when supporting Python 3.5 or earlier.
f-strings are compiled at parse time, making them faster than .format() or % formatting.
Conditional Statements
Use indentation to define code blocks
if age >= 18:
print("Adult")
elif age >= 13:
print("Teenager")
else:
print("Child") Conditional Statements
Python uses indentation (4 spaces recommended) instead of braces to define code blocks. This enforces readable code structure.
For simple conditions: result = 'Adult' if age >= 18 else 'Minor'
Python 3.10+ introduced match-case for pattern matching, similar to switch statements in other languages.
Data Structures
Lists
Ordered, mutable collections
fruits = ["apple", "banana", "cherry"]
fruits.append("orange")
fruits[0] # "apple"
fruits[-1] # "orange" (last item)
fruits[1:3] # ["banana", "cherry"] (slice) Lists
Use lists when you need an ordered collection that may change size, like a shopping cart or task queue.
O(1) for append/pop at end, O(n) for insert/remove at beginning. Use collections.deque for frequent operations at both ends.
Python lists are dynamic arrays. For numeric operations, use numpy arrays for better performance.
Dictionaries
Key-value pairs, like objects in JavaScript
person = {"name": "John", "age": 30}
person["city"] = "New York"
person.get("name") # "John"
person.keys() # dict_keys(['name', 'age', 'city']) Dictionaries
Perfect for lookups, caching, and representing structured data like JSON. O(1) average lookup time.
Use .get('key', default) to avoid KeyError exceptions. Returns None (or default) if key doesn't exist.
Python 3.7+ guarantees insertion order. Use OrderedDict only if you need explicit ordering behavior.
Sets
Unordered collection of unique elements
unique_nums = {1, 2, 3, 3, 4} # {1, 2, 3, 4}
unique_nums.add(5)
unique_nums.remove(1) Sets
Ideal for removing duplicates, membership testing, and set operations (union, intersection, difference).
O(1) for add, remove, and 'in' checks. Much faster than lists for membership testing.
Elements must be hashable (immutable). Can't store lists or dicts, but can store tuples.
Tuples
Immutable ordered collections
coordinates = (10, 20)
x, y = coordinates # Unpacking
immutable = (1, 2, 3) # Cannot be modified Tuples
Tuples are hashable (can be dict keys), slightly faster than lists, and signal intent that data shouldn't change.
For fixed collections like coordinates, RGB colors, or returning multiple values from functions.
Use namedtuple or dataclasses for more readable code: Point = namedtuple('Point', ['x', 'y'])
List Comprehensions
Basic Comprehension
Create lists in a single line
squares = [x**2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] Basic Comprehension
More Pythonic, often faster than equivalent for loops, and produces more readable one-liners for simple transformations.
If logic is complex or spans multiple lines, use a regular for loop for clarity. Readability counts!
Use (x**2 for x in range(10)) for memory efficiency with large datasets - evaluates lazily.
With Condition
Filter elements with if condition
even_squares = [x**2 for x in range(10) if x % 2 == 0]
# [0, 4, 16, 36, 64] With Condition
Chain with 'and/or': [x for x in range(20) if x % 2 == 0 and x > 5]
For transformation: [x**2 if x % 2 == 0 else x for x in range(10)] - note the different position!
Same as filter(lambda x: x % 2 == 0, range(10)) but comprehensions are more Pythonic.
Dict Comprehension
Create dictionaries efficiently
square_dict = {x: x**2 for x in range(5)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} Dict Comprehension
Transform or filter existing dicts: {k: v.upper() for k, v in data.items() if v}
Use zip: dict(zip(keys, values)) or {k: v for k, v in zip(keys, values)}
Also available: {x % 3 for x in range(10)} creates a set with unique values.
Functions
Basic Function
Functions with default parameters
def greet(name, greeting="Hello"):
return f"{greeting}, {name}!"
greet("Alice") # "Hello, Alice!"
greet("Bob", "Hi") # "Hi, Bob!" Basic Function
*args captures positional args as tuple, **kwargs captures keyword args as dict. Useful for flexible function signatures.
def greet(name: str, greeting: str = 'Hello') -> str: - helps IDEs and type checkers, but not enforced at runtime.
Never use mutable default args like def f(items=[]). Use None instead: def f(items=None): items = items or []
Lambda Functions
Anonymous functions for simple operations
square = lambda x: x**2
numbers = [1, 2, 3, 4]
squared = list(map(square, numbers)) # [1, 4, 9, 16] Lambda Functions
Short, throwaway functions - especially as arguments to sorted(), map(), filter(). Keep them simple and readable.
Single expression only, no statements. For anything complex, use regular def functions.
Often list comprehensions are cleaner: [x**2 for x in numbers] instead of list(map(lambda x: x**2, numbers))
Decorators
Modify function behavior without changing its code
def uppercase_decorator(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return result.upper()
return wrapper
@uppercase_decorator
def greet(name):
return f"hello, {name}"
greet("alice") # "HELLO, ALICE" Decorators
Logging, timing, authentication, caching (@functools.lru_cache), and retry logic. Very powerful for cross-cutting concerns.
Always use @wraps(func) in wrapper to preserve the original function's name and docstring.
@property, @staticmethod, @classmethod, @abstractmethod, @dataclass are commonly used built-in decorators.
Classes
Basic Class
__init__ is the constructor method
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
return f"Hi, I'm {self.name}"
person = Person("John", 30)
print(person.greet()) # "Hi, I'm John" Basic Class
self refers to the instance. Unlike other languages, Python requires explicit self as first parameter in instance methods.
For data containers, use @dataclass: @dataclass class Person: name: str; age: int - auto-generates __init__, __repr__, etc.
Use _name for 'protected' (convention) or __name for name mangling (becomes _ClassName__name). Python trusts developers.
Inheritance
Inherit from parent class using super()
class Student(Person):
def __init__(self, name, age, student_id):
super().__init__(name, age)
self.student_id = student_id
def study(self):
return f"{self.name} is studying" Inheritance
Python supports it: class A(B, C). Method Resolution Order (MRO) determines which method is called. Use sparingly.
Prefer composition ('has-a') over inheritance ('is-a') for flexibility. Student HAS a schedule vs Student IS a Person.
Use ABC: from abc import ABC, abstractmethod. Forces subclasses to implement certain methods.
Visual Concepts
Python Data Types
Overview of Python's built-in data types
Exception Handling Flow
How try/except blocks work in Python
List vs Tuple vs Set
Comparison of Python collection types
Find this helpful?
Check out more cheatsheets and learning resources, or get in touch for personalized training.