This note is for readers who can already program in C, Java, or JavaScript and want enough Python syntax to solve algorithm problems. It assumes familiarity with variables, branches, loops, arrays, hash maps, sets, stacks, queues, and recursion. It does not try to teach Python as a full application language.

The useful goal is transfer. The reader already knows the programming ideas. This note supplies Python’s spellings, defaults, common library tools, and traps that matter in algorithm practice.

Basic Translation

Python uses indentation instead of braces. A block starts after a colon and continues while the indentation level stays the same.

if x > 0:
    print("positive")
elif x == 0:
    print("zero")
else:
    print("negative")

The first syntax shifts are small but important:

Brace-language habitPython spelling
{ ... } blocksindented blocks after :
int x = 3 or let x = 3x = 3
true, false, nullTrue, False, None
&&, ||, !and, or, not
i++, i--i += 1, i -= 1
arr.length or arr.length()len(arr)
else ifelif

Python has no required semicolon at the end of a statement. Names do not need type declarations.

n = 5
name = "alice"
ok = True

Comments start with #.

# Count how many times each value appears.

Input and Output

Algorithm problems often require fast input. For small examples, input() is fine. For large input, use sys.stdin.readline.

import sys
 
line = sys.stdin.readline()
n = int(line)

A common contest pattern aliases readline as input.

import sys
input = sys.stdin.readline
 
n = int(input())
a = list(map(int, input().split()))

split() separates by whitespace and ignores the trailing newline. When reading a raw string, remove the newline explicitly.

s = input().strip()

Read several integers from one line with map.

n, m = map(int, input().split())

Read a list of integers.

a = list(map(int, input().split()))

Read an n by m integer grid.

grid = [list(map(int, input().split())) for _ in range(n)]

Read an n by m character grid.

grid = [list(input().strip()) for _ in range(n)]

For many output lines, collect strings and print once.

answers = []
 
for value in values:
    answers.append(str(value))
 
print("\n".join(answers))

Numbers and Operators

Python int grows automatically. There is no fixed 32-bit or 64-bit integer overflow in normal Python integer arithmetic.

x = 10**100

The division operators are different from C, Java, and JavaScript:

OperatorMeaning
/true division, returns a float
//floor division
%remainder
**exponentiation

Use // for integer midpoints and integer quotient logic.

mid = (left + right) // 2

Be careful with negative values. Python floor division rounds down, not toward zero.

-3 // 2  # -2
-3 % 2   # 1

Useful numeric functions are built in.

abs(x)
min(a, b)
max(a, b)
sum(values)

Use a large integer or infinity as a sentinel.

INF = 10**18
dist = [INF] * n

Python also supports chained comparisons.

if 0 <= x < n and 0 <= y < m:
    pass

Branches, Loops, and Ranges

Conditionals use if, elif, and else.

if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"
else:
    grade = "C"

Python for loops usually iterate over a range or directly over a collection.

for i in range(n):
    print(i)

range excludes the stop value.

range(n)          # 0, 1, ..., n - 1
range(1, n + 1)  # 1, 2, ..., n
range(n - 1, -1, -1)  # n - 1, n - 2, ..., 0

Iterate over values when the index is not needed.

for x in a:
    total += x

Use enumerate when both the index and value are needed.

for i, x in enumerate(a):
    print(i, x)

Use while when the loop condition is state-based.

while left <= right:
    mid = (left + right) // 2

break and continue work as in brace-based languages.

for x in a:
    if x < 0:
        continue
    if x == target:
        break

Lists

Python list is the everyday dynamic array for algorithm problems. It is closest to Java ArrayList or JavaScript Array, not to a fixed-size C array.

a = [3, 1, 4]
a.append(2)
last = a.pop()

Common operations:

OperationMeaningUsual cost
a[i]read or write by indexO(1)
a.append(x)add to the endamortized O(1)
a.pop()remove from the endO(1)
a.pop(0)remove from the frontO(n)
x in alinear membership checkO(n)
len(a)lengthO(1)

Use a list as a stack.

stack = []
stack.append(start)
 
while stack:
    x = stack.pop()

Python supports negative indexing.

a[-1]  # last element
a[-2]  # second-to-last element

Slicing creates a new list.

a[l:r]   # elements l through r - 1
a[:r]    # beginning through r - 1
a[l:]    # l through the end
a[::-1]  # reversed copy

Assignment copies the reference, not the list contents.

b = a      # b and a refer to the same list
c = a[:]   # shallow copy
d = list(a)

Use a list comprehension for simple construction.

squares = [x * x for x in a]
evens = [x for x in a if x % 2 == 0]

Create a two-dimensional list with a comprehension.

grid = [[0] * m for _ in range(n)]

Do not create a two-dimensional list by multiplying the inner list. It reuses the same row object.

bad = [[0] * m] * n

Strings

Python strings are immutable sequences of characters. They support indexing, slicing, and iteration.

s = "algorithm"
 
s[0]     # "a"
s[-1]    # "m"
s[1:4]   # "lgo"

Iterate over characters.

for ch in s:
    print(ch)

Because strings are immutable, build changed strings through a character list.

chars = list(s)
chars[0] = "A"
t = "".join(chars)

Collect pieces in a list and join them instead of repeatedly concatenating inside a large loop.

parts = []
 
for word in words:
    parts.append(word)
 
result = "".join(parts)

Use ord and chr for character codes.

index = ord(ch) - ord("a")
ch = chr(ord("a") + index)

Tuples and Unpacking

A tuple is an immutable fixed-size sequence. In algorithm code, tuples are useful for coordinates, pairs, states, and heap entries.

point = (r, c)
r, c = point

Multiple assignment makes swaps and state updates concise.

a, b = b, a

Tuples compare lexicographically. Python compares the first element, then the second, and so on.

(1, 2) < (1, 3)  # True

This matters for sorting and heaps.

items = [(2, "b"), (1, "c"), (1, "a")]
items.sort()
# [(1, "a"), (1, "c"), (2, "b")]

Directional movement is often written as a list of tuples.

directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]
 
for dr, dc in directions:
    nr = r + dr
    nc = c + dc

Dictionaries and Sets

Python dict is the normal hash map. It is closest to Java HashMap or JavaScript Map for algorithm purposes.

count = {}
 
for x in a:
    count[x] = count.get(x, 0) + 1

Use in to test whether a key exists.

if x in count:
    print(count[x])

Indexing a missing key raises KeyError.

value = count.get(x, 0)

collections.defaultdict is useful for grouping.

from collections import defaultdict
 
groups = defaultdict(list)
 
for name, team in pairs:
    groups[team].append(name)

collections.Counter is useful for frequency maps.

from collections import Counter
 
count = Counter(a)

Python set is the normal hash set. Use it for membership, duplicate removal, and visited tracking.

visited = set()
visited.add(start)
 
if node not in visited:
    visited.add(node)

Dictionary keys and set elements must be hashable. Lists are mutable and cannot be keys. Use tuples for coordinate keys.

seen = set()
seen.add((r, c))

Sorting

list.sort() sorts in place and returns None.

a.sort()

sorted() returns a new sorted list.

b = sorted(a)

Use reverse=True for descending order.

a.sort(reverse=True)

Use key for custom ordering. The key function returns the value Python should sort by.

people.sort(key=lambda p: p[1])

For multiple criteria, return a tuple.

# Sort by score descending, then name ascending.
people.sort(key=lambda p: (-p[1], p[0]))

Tuples and lists sort lexicographically by default.

pairs.sort()

Python sorting is stable. Equal-key items keep their previous relative order.

Queues, Heaps, Binary Search, and Other Libraries

Use collections.deque for a queue. A Python list is fine as a stack, but pop(0) on a list is O(n).

from collections import deque
 
q = deque()
q.append(start)
 
while q:
    node = q.popleft()

Use heapq for a priority queue. Python’s heap is a minimum heap.

import heapq
 
heap = []
heapq.heappush(heap, (dist, node))
 
while heap:
    dist, node = heapq.heappop(heap)

For a maximum heap, push negative priorities.

heapq.heappush(heap, -value)
value = -heapq.heappop(heap)

Use bisect for binary search in a sorted list.

from bisect import bisect_left, bisect_right
 
i = bisect_left(a, target)   # first index with a[i] >= target
j = bisect_right(a, target)  # first index with a[j] > target

Use itertools for small combinational search spaces.

from itertools import combinations, permutations, product
 
for pair in combinations(items, 2):
    pass
 
for order in permutations(items):
    pass
 
for bits in product([0, 1], repeat=n):
    pass

Use math for number-theory and exact integer helpers.

import math
 
math.gcd(a, b)
math.lcm(a, b)
math.isqrt(x)
math.comb(n, r)

Functions and Recursion

Define functions with def.

def add(a, b):
    return a + b

Python can return multiple values by returning a tuple.

def divmod_pair(a, b):
    return a // b, a % b
 
q, r = divmod_pair(10, 3)

Variables assigned inside a function are local to that function unless explicitly handled otherwise. In algorithm code, it is often simpler to pass values as parameters, return results, or mutate a list, dictionary, or set that was passed in.

def dfs(node, graph, visited):
    visited.add(node)
 
    for nxt in graph[node]:
        if nxt not in visited:
            dfs(nxt, graph, visited)

Python has a recursion limit. Increase it before deep DFS or recursive dynamic programming.

import sys
sys.setrecursionlimit(10**6)

Avoid mutable default arguments. The default object is created once and reused across calls.

def bad(path=[]):
    path.append(1)
    return path

Use None as the default and create the list inside the function.

def good(path=None):
    if path is None:
        path = []
    path.append(1)
    return path

Minimal Problem-Solving Template

A compact template for many algorithm problems looks like this:

import sys
from collections import deque, defaultdict, Counter
from bisect import bisect_left, bisect_right
import heapq
import math
 
input = sys.stdin.readline
 
 
def solve():
    n = int(input())
    a = list(map(int, input().split()))
 
    answer = 0
 
    # Write the algorithm here.
 
    print(answer)
 
 
if __name__ == "__main__":
    solve()

Not every problem needs every import. The important pattern is to put input parsing, data structure setup, algorithm logic, and output in predictable places.

Common Traps

The most common mistakes for C, Java, and JavaScript programmers are translation mistakes, not algorithm mistakes.

  • Python uses indentation as syntax.
  • range(n) stops at n - 1.
  • Python has no ++ or --.
  • Use and, or, and not, not &&, ||, and !.
  • Use len(a), not a.length.
  • / returns a float. Use // for integer division.
  • Python // floors for negative values.
  • Use == for value equality. Use is only for object identity, especially x is None.
  • list.sort() mutates the list and returns None.
  • A list assignment copies the reference, not the list contents.
  • [[0] * m] * n reuses the same inner list.
  • Strings are immutable.
  • heapq is a minimum heap by default.
  • Use deque.popleft() for queues instead of list.pop(0).
  • Dictionary lookup with a missing key raises KeyError.
  • Lists cannot be dictionary keys or set elements. Use tuples for coordinate keys.
  • Increase the recursion limit before deep recursive DFS.

What to Remember

Use this note as a translation checklist for algorithm problems. Get input and output right first, then choose the Python container that matches the algorithm.

Use list for arrays and stacks, deque for queues, dict and set for hash-based lookup, heapq for minimum-priority queues, and bisect for binary search on sorted lists.

Most mistakes come from carrying over brace-language habits too literally: range excludes the end, / is not integer division, assignment does not copy lists, strings are immutable, and [[0] * m] * n reuses the same inner list.