Python Tricks & Interview Patterns

Matrix inputs, one-liners, collections, itertools, competitive programming shortcuts & interview-ready patterns

Python
Contents
#

I/O & Matrix Input

Reading Input

# Single integer
n = int(input())

# Multiple integers on one line
a, b, c = map(int, input().split())

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

# N lines of input
lines = [input() for _ in range(n)]

Matrix Input Patterns

# Read N×M integer matrix
n, m = map(int, input().split())
matrix = [list(map(int, input().split())) for _ in range(n)]

# Read N×N matrix (square)
n = int(input())
grid = [list(map(int, input().split())) for _ in range(n)]

# Character grid (no spaces)
grid = [list(input()) for _ in range(n)]

# Transpose a matrix
transposed = list(zip(*matrix))         # tuples
transposed = [list(row) for row in zip(*matrix)]

# Flatten a matrix
flat = [x for row in matrix for x in row]

# Rotate 90° clockwise
rotated = [list(row) for row in zip(*matrix[::-1])]

# Create N×M matrix filled with zeros
mat = [[0] * m for _ in range(n)]
# ⚠️ NOT [[0]*m]*n — creates references to same list!

Fast I/O (Competitive Programming)

import sys
input = sys.stdin.readline   # much faster

# Read all input at once
data = sys.stdin.read().split()
idx = 0
n = int(data[idx]); idx += 1

# Fast output
out = []
for _ in range(n):
    out.append(str(result))
print("\n".join(out))
#

One-Liners & Comprehensions

# List comprehension with condition
evens = [x for x in range(20) if x % 2 == 0]

# Nested comprehension (flatten)
flat = [x for sub in nested for x in sub]

# Dict comprehension
sq = {x: x**2 for x in range(10)}

# Set comprehension
unique_lens = {len(w) for w in words}

# Conditional expression (ternary)
result = "even" if n % 2 == 0 else "odd"

# Swap variables
a, b = b, a

# Multiple assignment
x = y = z = 0

# Chain comparisons
if 1 <= x <= 10:  # same as 1 <= x and x <= 10

# Any / All
has_neg = any(x < 0 for x in nums)
all_pos = all(x > 0 for x in nums)

# Enumerate with start index
for i, val in enumerate(arr, start=1):

# Zip longest
from itertools import zip_longest
list(zip_longest(a, b, fillvalue=0))
#

Collections Module

from collections import Counter, defaultdict, deque, OrderedDict, namedtuple

# Counter — frequency counting
c = Counter("abracadabra")       # Counter({'a':5, 'b':2, 'r':2, 'c':1, 'd':1})
c.most_common(2)                 # [('a', 5), ('b', 2)]
c['a']                            # 5
c + Counter("abc")               # add counts
c - Counter("abc")               # subtract counts

# defaultdict — no KeyError
d = defaultdict(list)
d["key"].append(1)              # auto-creates list
d = defaultdict(int)
d["key"] += 1                    # auto-starts at 0

# deque — O(1) append/pop both ends
dq = deque([1, 2, 3])
dq.appendleft(0)                 # [0, 1, 2, 3]
dq.popleft()                     # 0
dq.rotate(1)                     # right rotate: [3, 1, 2]
dq.rotate(-1)                    # left rotate: [1, 2, 3]
dq = deque(maxlen=3)             # auto-discard oldest

# namedtuple — lightweight class
Point = namedtuple("Point", ["x", "y"])
p = Point(3, 4)
p.x, p.y                          # 3, 4
#

Itertools & Functools

from itertools import (
    permutations, combinations, combinations_with_replacement,
    product, chain, groupby, accumulate, starmap, count, cycle, repeat
)

# Permutations & Combinations
list(permutations([1,2,3]))         # 6 tuples: (1,2,3), (1,3,2)...
list(permutations([1,2,3], 2))      # 2-length perms
list(combinations([1,2,3], 2))      # [(1,2), (1,3), (2,3)]
list(combinations_with_replacement([1,2], 2))  # [(1,1),(1,2),(2,2)]

# Cartesian product
list(product("AB", "12"))           # [('A','1'),('A','2'),('B','1'),('B','2')]
list(product(range(3), repeat=2))   # all pairs (0,0)..(2,2)

# Chain — flatten iterables
list(chain([1,2], [3,4], [5]))    # [1, 2, 3, 4, 5]
list(chain.from_iterable([[1,2],[3,4]]))

# Groupby (must be sorted first!)
data = sorted(students, key=lambda s: s.grade)
for grade, group in groupby(data, key=lambda s: s.grade):
    print(grade, list(group))

# Accumulate — running totals
list(accumulate([1,2,3,4]))       # [1, 3, 6, 10]

Functools

from functools import lru_cache, reduce, partial, cache

# LRU Cache — memoization (great for DP!)
@lru_cache(maxlen=None)
def fib(n):
    if n < 2: return n
    return fib(n-1) + fib(n-2)

# @cache — simpler (Python 3.9+), unlimited
@cache
def expensive(x): ...

# Reduce
product_val = reduce(lambda a, b: a * b, [1,2,3,4])  # 24

# Partial — freeze arguments
add_ten = partial(lambda a, b: a + b, 10)
add_ten(5)  # 15
#

String Tricks

# Reverse
s[::-1]                           # "hello" → "olleh"

# Check palindrome
s == s[::-1]

# Count occurrences
s.count("ab")

# Split & join
words = s.split()
" ".join(words)
",".join(map(str, nums))           # "1,2,3"

# f-string formatting
f"{val:.2f}"                       # "3.14"
f"{val:08b}"                       # "00001010" (binary, 8 digits)
f"{val:,}"                         # "1,000,000"
f"{name!r}"                        # repr: "'hello'"
f"{val:>10}"                       # right-align, width 10
f"{val:^10}"                       # center-align

# Character operations
ord('a')                           # 97
chr(97)                            # 'a'
chr(ord('a') + 3)                  # 'd'

# Useful checks
s.isalpha()  s.isdigit()  s.isalnum()  s.isspace()

# Strip, replace
s.strip()  s.lstrip()  s.rstrip()
s.replace("old", "new")

# Translate table (fast char replacement)
table = str.maketrans("aeiou", "12345")
"hello".translate(table)           # "h2ll4"
#

Bitwise Tricks

# Basic operations
a & b    # AND
a | b    # OR
a ^ b    # XOR
~a       # NOT (flips bits)
a << n   # left shift (multiply by 2^n)
a >> n   # right shift (divide by 2^n)

# Check if power of 2
n > 0 and (n & (n - 1)) == 0

# Check if bit is set
bool(n & (1 << i))

# Set bit / clear bit / toggle bit
n | (1 << i)       # set bit i
n & ~(1 << i)      # clear bit i
n ^ (1 << i)       # toggle bit i

# Count set bits
bin(n).count("1")

# XOR tricks
a ^ 0 == a          # identity
a ^ a == 0          # self-cancel → find unique element!
a ^ b ^ b == a      # undo XOR

# Find missing number (1..n, one missing)
missing = 0
for i in range(1, n+1): missing ^= i
for x in arr: missing ^= x
#

Sorting Tricks

# Sort by key
arr.sort(key=lambda x: x[1])          # sort by second element
arr.sort(key=lambda x: (-x[1], x[0]))  # desc by [1], then asc by [0]

# Sort string by frequency then alphabetically
sorted(s, key=lambda c: (-freq[c], c))

# Custom comparator (legacy-style)
from functools import cmp_to_key
arr.sort(key=cmp_to_key(lambda a, b: -1 if a+b > b+a else 1))

# Heap (min-heap by default)
import heapq
heapq.heapify(arr)
heapq.heappush(arr, val)
smallest = heapq.heappop(arr)

# Max heap trick: negate values
heapq.heappush(heap, -val)
largest = -heapq.heappop(heap)

# K largest / smallest
heapq.nlargest(3, arr)
heapq.nsmallest(3, arr, key=lambda x: x[1])

# Bisect — binary search in sorted list
import bisect
bisect.bisect_left(arr, target)      # leftmost insertion point
bisect.bisect_right(arr, target)     # rightmost insertion point
bisect.insort(arr, val)               # insert maintaining order
#

Star Unpacking & Walrus

# Star unpacking
first, *rest = [1, 2, 3, 4]       # first=1, rest=[2,3,4]
first, *mid, last = [1,2,3,4]    # first=1, mid=[2,3], last=4

# Merge dicts
merged = {**dict1, **dict2}          # dict2 values win
merged = dict1 | dict2               # Python 3.9+

# Unpack into function args
args = [1, 2, 3]
func(*args)                          # func(1, 2, 3)
kwargs = {"a": 1, "b": 2}
func(**kwargs)                       # func(a=1, b=2)

# Walrus operator := (Python 3.8+)
if (n := len(arr)) > 10:
    print(f"Large: {n}")

# In while loops
while (line := input()) != "quit":
    process(line)

# In comprehensions
[y for x in data if (y := transform(x)) > 0]
#

Data Structure Patterns

# Stack (use list)
stack = []
stack.append(x)
stack.pop()
stack[-1]          # peek

# Queue (use deque)
from collections import deque
q = deque()
q.append(x)        # enqueue
q.popleft()        # dequeue

# Set operations
a | b   # union
a & b   # intersection
a - b   # difference
a ^ b   # symmetric difference
a <= b  # subset check

# Dict tricks
d.get(key, default)              # no KeyError
d.setdefault(key, []).append(v) # init if missing
d.pop(key, None)                 # remove, no error
{v: k for k, v in d.items()}    # reverse a dict

# SortedContainer (install: pip install sortedcontainers)
from sortedcontainers import SortedList
sl = SortedList([3, 1, 2])
sl.add(4)                         # O(log n)
sl.bisect_left(3)                # index
#

Common Interview Patterns

PatternWhen to UseKey Idea
Two PointersSorted array, pair sumleft=0, right=n-1, move inward
Sliding WindowSubarray/substring of size kExpand right, shrink left
HashMapFrequency, two-sumStore seen elements / counts
Binary SearchSorted data, min/max answerlo, hi, mid = (lo+hi)//2
BFS / DFSGraph/tree traversalQueue (BFS) / Stack or recursion (DFS)
Dynamic ProgrammingOverlapping subproblemsdp[i] = f(dp[i-1], ...)
BacktrackingPermutations, subsetsChoose, explore, un-choose
Monotonic StackNext greater elementKeep stack in sorted order
Union-FindConnected componentsparent[], find(), union()
TriePrefix search, autocompleteTree of characters

Two Pointers

# Pair with target sum (sorted array)
def two_sum_sorted(arr, target):
    l, r = 0, len(arr) - 1
    while l < r:
        s = arr[l] + arr[r]
        if s == target: return [l, r]
        elif s < target: l += 1
        else: r -= 1

Sliding Window

# Max sum subarray of size k
def max_sum_k(arr, k):
    window = sum(arr[:k])
    best = window
    for i in range(k, len(arr)):
        window += arr[i] - arr[i - k]
        best = max(best, window)
    return best

# Smallest subarray with sum >= target
def min_subarray_sum(arr, target):
    l = total = 0
    best = float("inf")
    for r in range(len(arr)):
        total += arr[r]
        while total >= target:
            best = min(best, r - l + 1)
            total -= arr[l]
            l += 1
    return best

Binary Search

# Standard binary search
def binary_search(arr, target):
    lo, hi = 0, len(arr) - 1
    while lo <= hi:
        mid = (lo + hi) // 2
        if arr[mid] == target: return mid
        elif arr[mid] < target: lo = mid + 1
        else: hi = mid - 1
    return -1

# Binary search on answer (min val satisfying condition)
lo, hi = 0, 10**9
while lo < hi:
    mid = (lo + hi) // 2
    if condition(mid): hi = mid
    else: lo = mid + 1
# answer = lo
#

Gotchas & Pitfalls

# ❌ Mutable default argument
def bad(lst=[]):         # shared across calls!
    lst.append(1)
    return lst

# ✅ Fix
def good(lst=None):
    lst = lst or []

# ❌ Matrix trap
grid = [[0] * 3] * 3    # 3 references to SAME list!
grid[0][0] = 1           # changes ALL rows!

# ✅ Fix
grid = [[0] * 3 for _ in range(3)]

# ❌ Modifying list during iteration
for item in lst:
    if condition: lst.remove(item)  # skips elements!

# ✅ Fix: use comprehension or iterate copy
lst = [x for x in lst if not condition]

# ❌ Integer comparison
a = 256; b = 256
a is b   # True (cached -5 to 256)
a = 257; b = 257
a is b   # False! Use == for value comparison

# ❌ Float precision
0.1 + 0.2 == 0.3        # False!
abs(0.1 + 0.2 - 0.3) < 1e-9  # True ✅

# Recursion limit
import sys
sys.setrecursionlimit(10**6)   # for deep recursion in CP
#

Quick Reference Table

TaskCode
Max / Min of listmax(arr), min(arr)
Sumsum(arr)
Sort descendingsorted(arr, reverse=True)
Unique elementslist(set(arr))
Flatten 2D[x for row in mat for x in row]
Frequency mapCounter(arr)
Remove duplicates (keep order)list(dict.fromkeys(arr))
Infinityfloat('inf'), float('-inf')
Max intsys.maxsize
Check emptyif not arr:
Index of elementarr.index(x) (raises ValueError)
Safe indexarr.index(x) if x in arr else -1
Map to intlist(map(int, strs))
Digits of number[int(d) for d in str(n)]
GCD / LCMmath.gcd(a,b), math.lcm(a,b) (3.9+)
Ceiling division-(-a // b) or math.ceil(a/b)
Back to top