Build, index, slice, mutate, sort and search Python lists, plus the copy semantics that trip people up.
xs = [3, 1, 2]
ys = [10, 20, 30]
words = ["kiwi", "fig", "banana"]
pairs = [("a", 3), ("b", 1)]
grid = [[1, 2], [3, 4]][], list()Two ways to make an empty list.
[0] * 5→ [0, 0, 0, 0, 0].
list(range(5)), list(range(2, 11, 3))→ [0, 1, 2, 3, 4], [2, 5, 8].
list("abc")Any iterable → list of its items → ['a', 'b', 'c'].
[[0] * 3 for _ in range(2)]2×3 grid of independent rows. [[0]*3]*2 shares ONE row — the classic trap.
[x * 2 for x in xs if x > 1]Comprehension with a filter → [6, 4].
xs[0], xs[-1]First and last item.
xs[1:], xs[:-1], xs[::2], xs[::-1]All but first / all but last / every 2nd / reversed copy.
len(xs)Item count.
xs.index(2)Position of first match; ValueError when absent.
xs.count(1)How many times a value appears.
2 in xs, 9 not in xsMembership test, O(n).
first, *rest = xsUnpack: first=3, rest=[1, 2].
xs[10:20]Slicing out of range gives [] — indexing out of range raises IndexError.
xs.append(4)Add to the end. In place; returns None.
xs.extend([5, 6])Add every item of another iterable (xs += [5, 6] does the same).
xs.insert(0, 9)Insert at an index; O(n).
xs.pop(), xs.pop(0)Remove and return the last / the first item.
xs.remove(1)Remove the first occurrence of a value; ValueError when absent.
del xs[0]Delete by index; del xs[1:] deletes a slice.
xs + [4, 5]New list; the originals are untouched.
xs[0:2] = [7, 8, 9]Slice assignment can change the length; xs.clear() empties it.
xs.sort()In place, returns None.
sorted(xs), sorted(xs, reverse=True)New sorted list; the original is untouched.
sorted(words, key=len)Sort by a key function → ['fig', 'kiwi', 'banana'].
sorted(pairs, key=lambda p: p[1])Sort tuples by their second item.
sorted(words, key=lambda w: (-len(w), w))Multi-key: longest first, then alphabetical.
xs.reverse(); list(reversed(xs))In place vs an iterator over a copy.
min(xs), max(xs), sum(xs)→ 1, 3, 6.
max(words, key=len)The longest word.
next((x for x in xs if x > 1), None)First match or a default, without scanning the rest.
import bisect
bisect.bisect_left([1, 3, 5], 4)Insertion index in a sorted list → 2 (binary search).
for i, x in enumerate(xs, start=1):
print(i, x)Index and item together; start defaults to 0.
for a, b in zip(xs, ys):
print(a, b)Parallel iteration; stops at the shortest (strict=True raises instead).
any(x > 2 for x in xs), all(x > 0 for x in xs)Short-circuit tests → True, True.
list(filter(None, [0, 1, "", "a", None]))Keep truthy items → [1, 'a'].
list(map(str, xs))Apply a function to each → ['3', '1', '2'].
[c for row in grid for c in row]Flatten one level → [1, 2, 3, 4].
from itertools import pairwise
list(pairwise([1, 2, 3]))Adjacent pairs → [(1, 2), (2, 3)] (3.10+).
ys2 = xsNOT a copy — both names point at the same list.
xs.copy(), xs[:], list(xs)Three shallow copies: nested lists inside are still shared.
import copy
copy.deepcopy(grid)Copy nested structures all the way down.
tuple(xs), set(xs)Immutable version / unique values (order lost).
list(dict.fromkeys([1, 1, 2, 3, 2]))De-duplicate but keep first-seen order → [1, 2, 3].
", ".join(map(str, xs))→ '3, 1, 2'; join needs strings.
Want the topic explained, not just listed? The Lists & Looping lesson walks through it with graded exercises. Preparing for interviews? See the interview prep track.