DEV Community

itzsrikanth
itzsrikanth

Posted on

CheatSheet: Python for DSA

Python DSA Cheatsheet - Complete Reference

Note: I took help of LLMs to arrange the structure and come up with few of the examples in the list below

Table of Contents

  1. Numeric Operations
  2. List / Array Operations
  3. String Operations
  4. Dictionary / HashMap Operations
  5. Set Operations
  6. Heap / Priority Queue
  7. Deque Operations
  8. Collections Module
  9. Itertools
  10. Matrix Operations
  11. Bit Manipulation
  12. Binary Search
  13. Common Patterns
  14. Input/Output Tricks

Numeric Operations

Setting min / max

import math

cost = float('inf')  # Infinity
cost = -float('inf') # Negative infinity
cost = math.inf      # Alternative
Enter fullscreen mode Exit fullscreen mode

Division Types

# Floor division
7 // 2  # Output: 3

# Regular division (returns float)
7 / 2   # Output: 3.5

# Ceiling division
import math
math.ceil(7 / 2)  # Output: 4

# Python's floor division with negative numbers
-7 // 2   # Output: -4 (rounds down/toward negative infinity)
int(-7 / 2)  # Output: -3 (truncates toward zero)
Enter fullscreen mode Exit fullscreen mode

Modulo Operations

# Positive modulo
7 % 3   # Output: 1

# Negative modulo (Python always returns positive result)
-7 % 3  # Output: 2

# To get true modulo
((a % b) + b) % b
Enter fullscreen mode Exit fullscreen mode

Power and Root

# Power
2 ** 10  # Output: 1024
pow(2, 10)  # Output: 1024

# Modular exponentiation (for large numbers)
pow(2, 10, 1000)  # Output: 24 (2^10 mod 1000)

# Square root
import math
math.sqrt(16)  # Output: 4.0
16 ** 0.5      # Output: 4.0
Enter fullscreen mode Exit fullscreen mode

GCD and LCM

import math

# GCD
math.gcd(12, 18)  # Output: 6

# Multiple GCD
from functools import reduce
reduce(math.gcd, [12, 18, 24])  # Output: 6

# LCM
def lcm(a, b):
    return abs(a * b) // math.gcd(a, b)

# Multiple LCM
from functools import reduce
reduce(lcm, [12, 18, 24])
Enter fullscreen mode Exit fullscreen mode

List / Array Operations

Initialization

# 1D array with zeros
arr = [0] * 5  # Output: [0, 0, 0, 0, 0]

# 2D array with zeros (CORRECT way)
matrix = [[0] * cols for _ in range(rows)]

# WRONG way (all rows reference same list!)
# matrix = [[0] * cols] * rows  # DON'T USE THIS

# Initialize with specific value
arr = [float('inf')] * 5

# List comprehension
squares = [x**2 for x in range(5)]  # Output: [0, 1, 4, 9, 16]
Enter fullscreen mode Exit fullscreen mode

Insertion

arr = [1, 2, 3]

# At the end - O(1)
arr.append(4)  # [1, 2, 3, 4]

# At specific index - O(n)
arr.insert(1, 5)  # [1, 5, 2, 3, 4]

# Extend with another list
arr.extend([6, 7])  # [1, 5, 2, 3, 4, 6, 7]
arr += [8, 9]       # Alternative
Enter fullscreen mode Exit fullscreen mode

Removal

arr = [1, 2, 3, 4, 5]

# Pop at the end - O(1)
last = arr.pop()  # Returns 5, arr = [1, 2, 3, 4]

# Pop at specific index - O(n)
first = arr.pop(0)  # Returns 1, arr = [2, 3, 4]

# Remove by value (first occurrence) - O(n)
arr.remove(3)  # arr = [2, 4]

# Clear all
arr.clear()  # arr = []
Enter fullscreen mode Exit fullscreen mode

Slicing (IMPORTANT!)

arr = [0, 1, 2, 3, 4, 5]

# Basic slicing [start:end:step]
arr[1:4]      # [1, 2, 3] (end is exclusive)
arr[:3]       # [0, 1, 2] (from start)
arr[3:]       # [3, 4, 5] (to end)
arr[:]        # [0, 1, 2, 3, 4, 5] (copy entire list)

# Step
arr[::2]      # [0, 2, 4] (every 2nd element)
arr[1::2]     # [1, 3, 5] (every 2nd starting from index 1)

# Reverse
arr[::-1]     # [5, 4, 3, 2, 1, 0]
arr[-1::-1]   # Same as above

# Negative indices
arr[-1]       # 5 (last element)
arr[-3:]      # [3, 4, 5] (last 3 elements)
arr[:-2]      # [0, 1, 2, 3] (all except last 2)
Enter fullscreen mode Exit fullscreen mode

Sorting

arr = [3, 1, 4, 1, 5, 9, 2]

# In-place sort - O(n log n)
arr.sort()  # arr is modified
arr.sort(reverse=True)  # Descending order

# Return new sorted list
sorted_arr = sorted(arr)  # arr is unchanged

# Custom sorting with key
students = [("Alice", 20), ("Bob", 18), ("Charlie", 22)]
sorted_students = sorted(students, key=lambda x: x[1])  # Sort by age

# Multi-level sorting
envelopes = [[5,4], [6,4], [6,7], [2,3]]
# Sort by x[0] ASC, then x[1] DESC
envelopes.sort(key=lambda x: (x[0], -x[1]))

# Sort with custom comparator (use functools.cmp_to_key)
from functools import cmp_to_key
def compare(a, b):
    return a - b  # Ascending
arr.sort(key=cmp_to_key(compare))
Enter fullscreen mode Exit fullscreen mode

Binary Search (bisect module)

from bisect import bisect_left, bisect_right, insort

arr = [1, 2, 4, 4, 5, 7]

# bisect_left: leftmost insertion point
bisect_left(arr, 4)   # Output: 2 (index of first 4)
bisect_left(arr, 3)   # Output: 2 (would insert before 4)

# bisect_right (or bisect): rightmost insertion point
bisect_right(arr, 4)  # Output: 4 (after last 4)

# Insert and maintain sorted order
insort(arr, 3)  # arr = [1, 2, 3, 4, 4, 5, 7]

# Check if element exists
def exists(arr, x):
    i = bisect_left(arr, x)
    return i < len(arr) and arr[i] == x
Enter fullscreen mode Exit fullscreen mode

List Comprehension and Filtering

# Basic list comprehension
squares = [x**2 for x in range(10)]

# With condition
evens = [x for x in range(10) if x % 2 == 0]

# Nested comprehension (flatten)
matrix = [[1, 2], [3, 4], [5, 6]]
flat = [val for row in matrix for val in row]  # [1, 2, 3, 4, 5, 6]

# Extract specific column from 2D list
arr = [["a", 1], ["b", 2], ["c", 3]]
second_col = [row[1] for row in arr]  # [1, 2, 3]

# Enumerate with comprehension
indexed = [(i, val) for i, val in enumerate(arr)]
Enter fullscreen mode Exit fullscreen mode

Other Useful Operations

arr = [3, 1, 4, 1, 5, 9, 2, 6]

# Min/Max
min(arr)  # 1
max(arr)  # 9
min(arr, default=0)  # Returns 0 if arr is empty

# Sum
sum(arr)  # 31

# Count occurrences
arr.count(1)  # 2

# Find index of element
arr.index(4)  # 2 (first occurrence)

# Check existence
4 in arr  # True

# Reverse in-place
arr.reverse()

# Length
len(arr)  # 8

# All/Any
all([True, True, False])  # False
any([False, False, True])  # True

# Zip (combine multiple lists)
list(zip([1, 2, 3], ['a', 'b', 'c']))  # [(1, 'a'), (2, 'b'), (3, 'c')]

# Unzip
pairs = [(1, 'a'), (2, 'b'), (3, 'c')]
nums, chars = zip(*pairs)  # nums = (1, 2, 3), chars = ('a', 'b', 'c')
Enter fullscreen mode Exit fullscreen mode

String Operations

Basic Operations

s = "hello world"

# Length
len(s)  # 11

# Access by index
s[0]    # 'h'
s[-1]   # 'd'

# Slicing (same as list)
s[0:5]  # "hello"
s[::-1] # "dlrow olleh" (reverse)

# Concatenation
s1 + " " + s2
"".join([s1, s2])  # More efficient for multiple strings

# Repeat
"abc" * 3  # "abcabcabc"
Enter fullscreen mode Exit fullscreen mode

String Methods

s = "Hello World"

# Case conversion
s.lower()      # "hello world"
s.upper()      # "HELLO WORLD"
s.title()      # "Hello World"
s.capitalize() # "Hello world"
s.swapcase()   # "hELLO wORLD"

# Check properties
s.isalpha()    # False (has space)
s.isdigit()    # False
s.isalnum()    # False
s.isspace()    # False

# Strip whitespace
"  hello  ".strip()   # "hello"
"  hello  ".lstrip()  # "hello  "
"  hello  ".rstrip()  # "  hello"

# Split and Join
"a,b,c".split(',')    # ['a', 'b', 'c']
"a b c".split()       # ['a', 'b', 'c'] (splits on any whitespace)
','.join(['a', 'b'])  # "a,b"

# Replace
s.replace('World', 'Python')  # "Hello Python"

# Find and Index
s.find('o')     # 4 (first occurrence, returns -1 if not found)
s.index('o')    # 4 (raises exception if not found)
s.rfind('o')    # 7 (last occurrence)
s.count('l')    # 3

# Check prefix/suffix
s.startswith('Hello')  # True
s.endswith('World')    # True
Enter fullscreen mode Exit fullscreen mode

String Building (Performance)

# SLOW - string concatenation in loop
result = ""
for c in chars:
    result += c  # Creates new string each time

# FAST - use list and join
result = ''.join(chars)

# For complex building
from io import StringIO
builder = StringIO()
builder.write("hello")
builder.write(" world")
result = builder.getvalue()  # "hello world"
Enter fullscreen mode Exit fullscreen mode

Character Operations

# ASCII conversion
ord('A')    # 65
chr(65)     # 'A'

# Check if character
c = 'a'
c.isalpha()   # True
c.isdigit()   # False
c.islower()   # True
c.isupper()   # False
Enter fullscreen mode Exit fullscreen mode

Dictionary / HashMap Operations

Initialization

# Empty dict
d = {}
d = dict()

# With initial values
d = {'a': 1, 'b': 2}
d = dict(a=1, b=2)
d = dict([('a', 1), ('b', 2)])

# From keys with default value
keys = ['a', 'b', 'c']
d = dict.fromkeys(keys, 0)  # {'a': 0, 'b': 0, 'c': 0}
Enter fullscreen mode Exit fullscreen mode

Access and Modification

d = {'a': 1, 'b': 2}

# Access
d['a']           # 1 (raises KeyError if not exists)
d.get('a')       # 1 (returns None if not exists)
d.get('c', 0)    # 0 (custom default)

# Set
d['c'] = 3       # Add or update

# Delete
del d['a']
value = d.pop('b')         # Remove and return value
value = d.pop('x', None)   # Safe pop with default

# Check existence
'a' in d         # True
'a' not in d     # False
Enter fullscreen mode Exit fullscreen mode

Iteration

d = {'a': 1, 'b': 2, 'c': 3}

# Keys
for key in d:           # Iterate over keys
    print(key)

for key in d.keys():    # Explicit
    print(key)

# Values
for val in d.values():
    print(val)

# Key-value pairs
for key, val in d.items():
    print(key, val)
Enter fullscreen mode Exit fullscreen mode

Useful Operations

# Get all keys/values as list
list(d.keys())    # ['a', 'b', 'c']
list(d.values())  # [1, 2, 3]

# Update dictionary
d1 = {'a': 1, 'b': 2}
d2 = {'b': 3, 'c': 4}
d1.update(d2)     # d1 = {'a': 1, 'b': 3, 'c': 4}

# Merge dictionaries (Python 3.9+)
d3 = d1 | d2

# Copy
d_copy = d.copy()  # Shallow copy

# Clear
d.clear()

# Length
len(d)

# setdefault (get or set if not exists)
d.setdefault('d', 0)  # Returns 0 and sets d['d'] = 0 if not exists
Enter fullscreen mode Exit fullscreen mode

Sorting Dictionary

d = {'b': 2, 'a': 1, 'c': 3}

# Sort by key
sorted_d = dict(sorted(d.items()))

# Sort by value
sorted_d = dict(sorted(d.items(), key=lambda x: x[1]))

# Sort by value (descending)
sorted_d = dict(sorted(d.items(), key=lambda x: x[1], reverse=True))
Enter fullscreen mode Exit fullscreen mode

Set Operations

Initialization

# Empty set (NOT {})
s = set()

# With values
s = {1, 2, 3}
s = set([1, 2, 3])
Enter fullscreen mode Exit fullscreen mode

Basic Operations

s = {1, 2, 3}

# Add
s.add(4)        # {1, 2, 3, 4}

# Remove
s.remove(2)     # Raises KeyError if not exists
s.discard(2)    # No error if not exists
s.pop()         # Remove and return arbitrary element

# Check membership
2 in s          # True
5 not in s      # True

# Length
len(s)          # 3

# Clear
s.clear()
Enter fullscreen mode Exit fullscreen mode

Set Operations

s1 = {1, 2, 3, 4}
s2 = {3, 4, 5, 6}

# Union
s1 | s2                # {1, 2, 3, 4, 5, 6}
s1.union(s2)           # Same

# Intersection
s1 & s2                # {3, 4}
s1.intersection(s2)    # Same

# Difference
s1 - s2                # {1, 2} (in s1 but not s2)
s1.difference(s2)      # Same

# Symmetric difference (XOR)
s1 ^ s2                # {1, 2, 5, 6}
s1.symmetric_difference(s2)  # Same

# Subset/Superset
s1.issubset(s2)        # False
s1.issuperset(s2)      # False
s1.isdisjoint(s2)      # False
Enter fullscreen mode Exit fullscreen mode

Heap / Priority Queue

import heapq

# Min heap by default
heap = []

# Push - O(log n)
heapq.heappush(heap, 3)
heapq.heappush(heap, 1)
heapq.heappush(heap, 4)

# Pop min - O(log n)
min_val = heapq.heappop(heap)  # 1

# Peek min - O(1)
min_val = heap[0]  # Don't pop

# Heapify existing list - O(n)
arr = [3, 1, 4, 1, 5, 9, 2]
heapq.heapify(arr)  # arr is now a heap

# Push and pop in one operation
heapq.heappushpop(heap, 5)  # Push 5, then pop min
heapq.heapreplace(heap, 5)  # Pop min, then push 5

# N largest/smallest elements
heapq.nlargest(3, arr)   # [9, 5, 4]
heapq.nsmallest(3, arr)  # [1, 1, 2]

# Max heap trick (negate values)
max_heap = []
heapq.heappush(max_heap, -3)
heapq.heappush(max_heap, -1)
max_val = -heapq.heappop(max_heap)  # 3

# Heap with custom objects
heap = []
heapq.heappush(heap, (priority, item))  # Use tuple
Enter fullscreen mode Exit fullscreen mode

Deque Operations

from collections import deque

# Initialize
dq = deque()
dq = deque([1, 2, 3])
dq = deque([1, 2, 3], maxlen=5)  # Fixed size

# Append - O(1)
dq.append(4)        # Add to right: [1, 2, 3, 4]
dq.appendleft(0)    # Add to left: [0, 1, 2, 3, 4]

# Pop - O(1)
dq.pop()            # Remove from right, returns 4
dq.popleft()        # Remove from left, returns 0

# Extend - O(k)
dq.extend([5, 6])        # [1, 2, 3, 5, 6]
dq.extendleft([0, -1])   # [-1, 0, 1, 2, 3, 5, 6]

# Access
dq[0]              # First element
dq[-1]             # Last element

# Rotate
dq.rotate(1)       # Rotate right: [6, 1, 2, 3, 5]
dq.rotate(-1)      # Rotate left: [1, 2, 3, 5, 6]

# Other operations
dq.count(2)        # Count occurrences
dq.remove(3)       # Remove first occurrence
dq.reverse()       # Reverse in-place
dq.clear()         # Clear all
len(dq)            # Length
Enter fullscreen mode Exit fullscreen mode

Collections Module

Counter

from collections import Counter

# Initialize
c = Counter([1, 2, 2, 3, 3, 3])  # Counter({3: 3, 2: 2, 1: 1})
c = Counter("hello")              # Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1})

# Most common
c.most_common(2)   # [(3, 3), (2, 2)]

# Access counts
c[2]               # 2
c[5]               # 0 (no KeyError)

# Update
c.update([1, 1, 2])

# Subtract
c.subtract([1, 2])

# Arithmetic operations
c1 = Counter({'a': 3, 'b': 1})
c2 = Counter({'a': 1, 'b': 2})
c1 + c2            # Counter({'a': 4, 'b': 3})
c1 - c2            # Counter({'a': 2}) (keeps only positive)

# Convert to dict
dict(c)
Enter fullscreen mode Exit fullscreen mode

defaultdict

from collections import defaultdict

# With int (default 0)
d = defaultdict(int)
d['a'] += 1        # No KeyError, starts at 0

# With list (default [])
d = defaultdict(list)
d['a'].append(1)   # No KeyError, starts with []

# With set
d = defaultdict(set)
d['a'].add(1)

# With lambda
d = defaultdict(lambda: float('inf'))

# Convert to normal dict
dict(d)
Enter fullscreen mode Exit fullscreen mode

OrderedDict (less needed in Python 3.7+)

from collections import OrderedDict

# Maintains insertion order (dicts do this by default now)
d = OrderedDict()
d['a'] = 1
d['b'] = 2

# Move to end
d.move_to_end('a')  # Move 'a' to end

# Pop last
d.popitem(last=True)   # Pop from end
d.popitem(last=False)  # Pop from beginning
Enter fullscreen mode Exit fullscreen mode

Itertools

from itertools import *

# Combinations
list(combinations([1, 2, 3], 2))  # [(1, 2), (1, 3), (2, 3)]

# Permutations
list(permutations([1, 2, 3], 2))  # [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]

# Product (Cartesian product)
list(product([1, 2], ['a', 'b']))  # [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]

# Combinations with replacement
list(combinations_with_replacement([1, 2], 2))  # [(1, 1), (1, 2), (2, 2)]

# Chain (flatten)
list(chain([1, 2], [3, 4]))  # [1, 2, 3, 4]

# Accumulate (cumulative sum by default)
list(accumulate([1, 2, 3, 4]))  # [1, 3, 6, 10]
list(accumulate([1, 2, 3, 4], max))  # [1, 2, 3, 4] (running max)

# Groupby
data = [('a', 1), ('a', 2), ('b', 3), ('b', 4)]
for key, group in groupby(data, key=lambda x: x[0]):
    print(key, list(group))
# Output: a [('a', 1), ('a', 2)]
#         b [('b', 3), ('b', 4)]

# Cycle (infinite)
counter = 0
for item in cycle([1, 2, 3]):
    print(item)
    counter += 1
    if counter > 10:
        break

# Repeat
list(repeat(10, 3))  # [10, 10, 10]

# Islice (slice iterator)
list(islice(range(10), 2, 8, 2))  # [2, 4, 6]

# Pairwise (Python 3.10+)
list(pairwise([1, 2, 3, 4]))  # [(1, 2), (2, 3), (3, 4)]
Enter fullscreen mode Exit fullscreen mode

Matrix Operations

# Initialize matrix
rows, cols = 3, 4
matrix = [[0] * cols for _ in range(rows)]

# Fill with specific value
matrix = [[1] * cols for _ in range(rows)]

# Traverse
for i in range(rows):
    for j in range(cols):
        print(matrix[i][j])

# Get dimensions
rows = len(matrix)
cols = len(matrix[0]) if matrix else 0

# Transpose
transposed = [[matrix[j][i] for j in range(rows)] for i in range(cols)]
# Or using zip
transposed = list(map(list, zip(*matrix)))

# Rotate 90 degrees clockwise
rotated = [[matrix[rows-1-j][i] for j in range(rows)] for i in range(cols)]

# Flatten
flat = [val for row in matrix for val in row]

# Diagonal traversal
for i in range(rows):
    print(matrix[i][i])  # Main diagonal

# 4-directional movement
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]  # right, down, left, up
for dx, dy in directions:
    new_x, new_y = x + dx, y + dy

# 8-directional movement
directions = [(-1,-1), (-1,0), (-1,1), (0,-1), (0,1), (1,-1), (1,0), (1,1)]
Enter fullscreen mode Exit fullscreen mode

Bit Manipulation

# Basic operations
x = 5  # 101 in binary

# AND
x & 1     # Check if odd: 1 (True)
x & (x-1) # Remove rightmost set bit: 4 (100)

# OR
x | 1     # Set rightmost bit: 5

# XOR
x ^ 1     # Flip rightmost bit: 4
a ^ a     # Always 0
a ^ 0     # Always a

# NOT
~x        # Flip all bits: -6

# Left shift (multiply by 2)
x << 1    # 10 (1010)

# Right shift (divide by 2)
x >> 1    # 2 (10)

# Check if power of 2
(x & (x-1)) == 0 and x != 0

# Count set bits
bin(x).count('1')  # 2

# Get bit at position i
(x >> i) & 1

# Set bit at position i
x | (1 << i)

# Clear bit at position i
x & ~(1 << i)

# Toggle bit at position i
x ^ (1 << i)

# Get rightmost set bit
x & -x

# Common tricks
x & 1           # Check if odd
x & (x-1)       # Remove rightmost 1
x | (x+1)       # Set rightmost 0
x & -x          # Get rightmost 1
Enter fullscreen mode Exit fullscreen mode

Binary Search

# Template 1: Find exact value
def binary_search(arr, target):
    left, right = 0, len(arr) - 1
    while left <= right:
        mid = left + (right - left) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    return -1

# Template 2: Find leftmost position
def binary_search_left(arr, target):
    left, right = 0, len(arr)
    while left < right:
        mid = left + (right - left) // 2
        if arr[mid] < target:
            left = mid + 1
        else:
            right = mid
    return left

# Template 3: Find rightmost position
def binary_search_right(arr, target):
    left, right = 0, len(arr)
    while left < right:
        mid = left + (right - left) // 2
        if arr[mid] <= target:
            left = mid + 1
        else:
            right = mid
    return left - 1

# Using bisect module
from bisect import bisect_left, bisect_right

# Find leftmost >= target
idx = bisect_left(arr, target)

# Find rightmost <= target
idx = bisect_right(arr, target) - 1
Enter fullscreen mode Exit fullscreen mode

Common Patterns

Sliding Window

# Fixed size 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_sum

# Variable size window
def longest_substring_k_distinct(s, k):
    left = 0
    max_len = 0
    char_count = {}

    for right in range(len(s)):
        char_count[s[right]] = char_count.get(s[right], 0) + 1

        while len(char_count) > k:
            char_count[s[left]] -= 1
            if char_count[s[left]] == 0:
                del char_count[s[left]]
            left += 1

        max_len = max(max_len, right - left + 1)

    return max_len
Enter fullscreen mode Exit fullscreen mode

Two Pointers

# Opposite direction
def two_sum_sorted(arr, target):
    left, right = 0, len(arr) - 1
    while left < right:
        curr_sum = arr[left] + arr[right]
        if curr_sum == target:
            return [left, right]
        elif curr_sum < target:
            left += 1
        else:
            right -= 1
    return [-1, -1]

# Same direction
def remove_duplicates(arr):
    if not arr:
        return 0

    slow = 0
    for fast in range(1, len(arr)):
        if arr[fast] != arr[slow]:
            slow += 1
            arr[slow] = arr[fast]

    return slow + 1
Enter fullscreen mode Exit fullscreen mode

Prefix Sum

# 1D prefix sum
def prefix_sum(arr):
    prefix = [0]
    for num in arr:
        prefix.append(prefix[-1] + num)
    return prefix

# Range sum query
prefix = prefix_sum(arr)
range_sum = prefix[right+1] - prefix[left]

# 2D prefix sum
def build_prefix_2d(matrix):
    rows, cols = len(matrix), len(matrix[0])
    prefix = [[0] * (cols+1) for _ in range(rows+1)]

    for i in range(1, rows+1):
        for j in range(1, cols+1):
            prefix[i][j] = (matrix[i-1][j-1] + 
                           prefix[i-1][j] + 
                           prefix[i][j-1] - 
                           prefix[i-1][j-1])
    return prefix

# Range sum 2D
def range_sum_2d(prefix, r1, c1, r2, c2):
    return (prefix[r2+1][c2+1] - 
            prefix[r1][c2+1] - 
            prefix[r2+1][c1] + 
            prefix[r1][c1])
Enter fullscreen mode Exit fullscreen mode

Fast/Slow Pointers (Cycle Detection)

# Floyd's 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 False

# Find cycle start
def detect_cycle(head):
    slow = fast = head
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
        if slow == fast:
            slow = head
            while slow != fast:
                slow = slow.next
                fast = fast.next
            return slow
    return None
Enter fullscreen mode Exit fullscreen mode

Monotonic Stack

# Next greater element
def next_greater_elements(arr):
    n = len(arr)
    result = [-1] * n
    stack = []  # Store indices

    for i in range(n):
        while stack and arr[stack[-1]] < arr[i]:
            result[stack.pop()] = arr[i]
        stack.append(i)

    return result

# Previous smaller element
def previous_smaller_elements(arr):
    n = len(arr)
    result = [-1] * n
    stack = []

    for i in range(n):
        while stack and arr[stack[-1]] >= arr[i]:
            stack.pop()
        if stack:
            result[i] = arr[stack[-1]]
        stack.append(i)

    return result
Enter fullscreen mode Exit fullscreen mode

Input/Output Tricks

# Fast input (for competitive programming)
import sys
input = sys.stdin.readline

# Read single integer
n = int(input())

# Read multiple integers from one line
a, b, c = map(int, input().split())

# Read list of integers
arr = list(map(int, input().split()))

# Read multiple lines
lines = sys.stdin.readlines()

# Fast output
print(*arr)  # Prints list elements separated by space

# Format output
print(f"{value:.2f}")  # 2 decimal places
print(f"{value:05d}")  # Pad with zeros to width 5

# Multiple test cases
t = int(input())
for _ in range(t):
    # Solve each test case
    pass

# EOF handling
try:
    while True:
        line = input()
        # Process line
except EOFError:
    pass
Enter fullscreen mode Exit fullscreen mode

Miscellaneous

Lambda Functions

# Basic lambda
square = lambda x: x**2

# Multiple arguments
add = lambda x, y: x + y

# With conditional
max_fn = lambda x, y: x if x > y else y

# In sorting
arr.sort(key=lambda x: (x[0], -x[1]))

# In filter
evens = list(filter(lambda x: x % 2 == 0, arr))

# In map
squares = list(map(lambda x: x**2, arr))
Enter fullscreen mode Exit fullscreen mode

Functools

from functools import reduce, lru_cache, cmp_to_key

# Reduce
product = reduce(lambda x, y: x * y, [1, 2, 3, 4])  # 24

# LRU Cache (memoization)
@lru_cache(maxsize=None)
def fib(n):
    if n <= 1:
        return n
    return fib(n-1) + fib(n-2)

# Custom comparator
def compare(a, b):
    return a - b
arr.sort(key=cmp_to_key(compare))
Enter fullscreen mode Exit fullscreen mode

Try-Except

# Basic
try:
    result = 10 / 0
except ZeroDivisionError:
    print("Cannot divide by zero")

# Multiple exceptions
try:
    # code
except (ValueError, TypeError) as e:
    print(e)

# Catch all
try:
    # code
except Exception as e:
    print(e)

# Finally
try:
    # code
finally:
    # Always executes
    pass
Enter fullscreen mode Exit fullscreen mode

Top comments (0)