Reference
Reference
Common Patterns & Idioms
Swap Variables
# Pythonic
a, b = b, a
# Without temp variable (math trick)
a = a + b
b = a - b
a = a - bConditional Assignment (Ternary)
status = "adult" if age >= 18 else "minor"
# Chain ternary (use sparingly)
category = "low" if value < 3 else "medium" if value < 7 else "high"Default Values with or
name = user_input or "Anonymous"
count = get_count() or 0
# Caution: Fails if 0 or "" are valid values
value = 0
result = value or 10 # Returns 10, not 0!Safe Dictionary Access
# Use get() with default
value = d.get('key', 'default')
# Nested access
value = d.get('level1', {}).get('level2', 'default')
# setdefault for grouping
groups = {}
for item in items:
groups.setdefault(item.category, []).append(item)List/Dict Unpacking
# Unpack list
first, *rest = [1, 2, 3, 4] # first=1, rest=[2,3,4]
first, *middle, last = [1, 2, 3, 4, 5]
# Unpack dict
d = {'a': 1, 'b': 2}
**d in function call passes as keyword argumentsEnumerate with Start
for i, item in enumerate(items, start=1):
print(f"{i}. {item}")Zip for Parallel Iteration
names = ['Alice', 'Bob']
ages = [30, 25]
for name, age in zip(names, ages):
print(f"{name}: {age}")
# Create dict from two lists
d = dict(zip(names, ages))Flatten List
# Simple nested list
nested = [[1, 2], [3, 4], [5]]
flat = [item for sublist in nested for item in sublist]
# Using itertools
import itertools
flat = list(itertools.chain.from_iterable(nested))Remove Duplicates (Preserve Order)
# Using dict (Python 3.7+)
items = [1, 2, 2, 3, 1, 4]
unique = list(dict.fromkeys(items))
# Using seen set
def remove_duplicates(items):
seen = set()
result = []
for item in items:
if item not in seen:
seen.add(item)
result.append(item)
return resultCheck if All/Any Elements Match
# All elements satisfy condition
all(x > 0 for x in numbers)
# Any element satisfies condition
any(x < 0 for x in numbers)
# String contains digit
any(c.isdigit() for c in string)Find Index of Element
items = ['a', 'b', 'c']
# Index of first occurrence
idx = items.index('b') # 1
# With error handling
try:
idx = items.index('x')
except ValueError:
idx = -1
# All indices of element
indices = [i for i, x in enumerate(items) if x == 'b']Sort with Custom Key
# Sort by length
words = ['apple', 'pie', 'banana']
sorted(words, key=len)
# Sort dict by value
d = {'a': 3, 'b': 1, 'c': 2}
sorted_items = sorted(d.items(), key=lambda x: x[1])
sorted_dict = dict(sorted_items)
# Multiple sort criteria
students = [('Alice', 85), ('Bob', 85), ('Charlie', 90)]
sorted(students, key=lambda x: (-x[1], x[0])) # Score desc, name ascGotchas & Pitfalls
Mutable Default Arguments
# Bad
def append_to(item, lst=[]):
lst.append(item)
return lst
append_to(1) # [1]
append_to(2) # [1, 2] - Unexpected!
# Good
def append_to(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lstLate Binding in Closures
# Bad
functions = []
for i in range(3):
functions.append(lambda: i)
for f in functions:
print(f()) # 2, 2, 2 (all reference same i)
# Good: use default argument
functions = []
for i in range(3):
functions.append(lambda i=i: i)
for f in functions:
print(f()) # 0, 1, 2Modifying List While Iterating
# Bad
numbers = [1, 2, 3, 4, 5]
for num in numbers:
if num % 2 == 0:
numbers.remove(num) # Causes issues!
# Good: iterate over copy
for num in numbers[:]:
if num % 2 == 0:
numbers.remove(num)
# Better: use list comprehension
numbers = [n for n in numbers if n % 2 != 0]Integer Division
# Python 3
10 / 3 # 3.3333... (true division)
10 // 3 # 3 (floor division)
-10 // 3 # -4 (rounds toward negative infinity)Truthy/Falsy Confusion
value = 0
if value: # False (0 is falsy)
...
# Explicit check when 0 is valid
if value is not None:
...String Concatenation in Loop
# Slow (creates new string each time)
result = ""
for s in strings:
result += s
# Fast (join is optimized)
result = "".join(strings)Exception Handling in Loop
# Bad: Exception escapes loop
for item in items:
process(item) # Stops on first error
# Good: Handle per item
for item in items:
try:
process(item)
except Exception as e:
logging.error(f"Failed to process {item}: {e}")
continueCheat Sheets
Time Complexity Quick Reference
| Operation | List | Set | Dict |
|---|---|---|---|
| Access by index/key | O(1) | N/A | O(1)* |
| Search | O(n) | O(1)* | O(1)* |
| Insert (end/any) | O(1) | O(1)* | O(1)* |
| Insert (middle) | O(n) | N/A | N/A |
| Delete | O(n) | O(1)* | O(1)* |
| Iterate | O(n) | O(n) | O(n) |
*Average case; worst case O(n)
String Methods
s.upper(), s.lower(), s.title(), s.capitalize()
s.strip(), s.lstrip(), s.rstrip()
s.split(sep), s.join(iterable)
s.replace(old, new)
s.startswith(prefix), s.endswith(suffix)
s.find(sub), s.index(sub)
s.count(sub)
s.isdigit(), s.isalpha(), s.isalnum()List Methods
lst.append(x) # Add to end
lst.insert(i, x) # Insert at index
lst.extend(iterable) # Add multiple
lst.remove(x) # Remove first occurrence
lst.pop() # Remove last
lst.pop(i) # Remove at index
lst.clear() # Remove all
lst.index(x) # Find index
lst.count(x) # Count occurrences
lst.sort() # Sort in-place
lst.reverse() # Reverse in-placeDictionary Methods
d.get(key, default)
d.setdefault(key, default)
d.keys(), d.values(), d.items()
d.pop(key), d.popitem()
d.clear()
d.update(other_dict)
d1 | d2 # Merge (Python 3.9+)Interview Prep
Common Algorithm Patterns
Two Pointers:
def two_sum_sorted(arr, target):
left, right = 0, len(arr) - 1
while left < right:
current = arr[left] + arr[right]
if current == target:
return [left, right]
elif current < target:
left += 1
else:
right -= 1
return NoneSliding Window:
def max_sum_subarray(arr, k):
window_sum = sum(arr[:k])
max_sum = window_sum
for i in range(k, len(arr)):
window_sum += arr[i] - arr[i - k]
max_sum = max(max_sum, window_sum)
return max_sumFast & Slow Pointers (Cycle Detection):
def has_cycle(head):
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return FalseBinary Search:
def binary_search(arr, target):
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1BFS (Level-order traversal):
from collections import deque
def bfs(root):
if not root:
return []
queue = deque([root])
result = []
while queue:
node = queue.popleft()
result.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return resultDFS (Recursive):
def dfs(node, visited=None):
if visited is None:
visited = set()
if node in visited:
return
visited.add(node)
process(node)
for neighbor in node.neighbors:
dfs(neighbor, visited)Common Interview Questions
- Reverse a string
- Check if palindrome
- Find two numbers that sum to target (Two Sum)
- Merge two sorted arrays
- Find missing number in array
- Detect cycle in linked list
- Validate balanced parentheses
- Find longest substring without repeating characters
- Binary tree level-order traversal
- Implement LRU cache
Tips
- Clarify requirements before coding
- Think out loud - explain your approach
- Start with brute force, then optimize
- Test with edge cases: empty input, single element, duplicates
- Analyze time/space complexity
- Write clean, readable code
- Ask about trade-offs: time vs space, readability vs performance
Python Gotchas Summary
- Mutable default arguments
- Late binding in closures
- Modifying list while iterating
- Integer division behavior
- Truthy/falsy values (0, “”, [], etc.)
- Dictionary key order (guaranteed in Python 3.7+)
- Shallow vs deep copy
- Global vs local scope
- Iterator exhaustion (map, zip, generators)
- String immutability
Last updated on