|$ curl https://forge-ai.dev/api/markdown?path=docs/python/data-structures
$cat docs/python-—-data-structures.md
updated Recently·20 min read·published

Python — Data Structures

PythonBeginner to Intermediate
Introduction

Python provides four built-in data structures: lists, tuples, dictionaries, and sets. Each has different characteristics for mutability, ordering, and performance.

Lists

Lists are ordered, mutable, and can contain heterogeneous elements. They are implemented as dynamic arrays.

lists.py
Python
1# Creation
2empty = []
3nums = [1, 2, 3, 4, 5]
4mixed = [1, "hello", 3.14, True]
5nested = [[1, 2], [3, 4, 5]]
6
7# From other iterables
8list("abc") # → ['a', 'b', 'c']
9range(5) # → range(0, 5) (lazy)
10list(range(5)) # → [0, 1, 2, 3, 4]
11
12# Indexing (0-based)
13print(nums[0]) # → 1
14print(nums[-1]) # → 5 (last element)
15print(nums[-2]) # → 4 (second from last)
16
17# Slicing [start:stop:step]
18print(nums[1:3]) # → [2, 3]
19print(nums[:3]) # → [1, 2, 3]
20print(nums[::2]) # → [1, 3, 5]
21print(nums[::-1]) # → [5, 4, 3, 2, 1] (reversed)
22
23# Methods
24nums.append(6) # add to end → [1,2,3,4,5,6]
25nums.extend([7, 8]) # merge → [1,2,3,4,5,6,7,8]
26nums.insert(0, 0) # insert at position → [0,1,2,3,4,5,6,7,8]
27nums.pop() # remove & return last → 8
28nums.pop(0) # remove & return at index → 0
29nums.remove(3) # remove first occurrence of 3
30nums.clear() # remove all
31
32# Searching
33nums = [1, 2, 3, 2, 4]
34print(nums.index(2)) # → 1 (first occurrence)
35print(nums.count(2)) # → 2 (how many times)
36print(5 in nums) # → False (membership)
37
38# Ordering
39nums.sort() # ascending in-place
40nums.sort(reverse=True) # descending in-place
41sorted(nums) # returns new sorted list
42nums.reverse() # reverse in-place
43
44# Copying
45copy1 = nums.copy() # shallow copy
46copy2 = nums[:] # shallow copy via slice
47import copy
48deep = copy.deepcopy(nested) # deep copy for nested
Tuples

Tuples are ordered, immutable sequences. They are fixed-size and can be used as dictionary keys (unlike lists).

tuples.py
Python
1# Creation
2empty = ()
3single = (1,) # trailing comma required!
4coords = (10, 20)
5named = ("Alice", 30, "Engineer")
6
7# Parentheses optional (tuple packing)
8point = 10, 20
9
10# Tuple unpacking (destructuring)
11x, y = point
12print(x) # → 10
13
14# Swapping via tuple
15a, b = b, a
16
17# Unpacking with *
18first, *rest = [1, 2, 3, 4]
19print(first) # → 1
20print(rest) # → [2, 3, 4]
21
22# Named tuples (like lightweight objects)
23from collections import namedtuple
24Point = namedtuple("Point", ["x", "y"])
25p = Point(10, y=20)
26print(p.x) # → 10 (attribute access)
27print(p[0]) # → 10 (index access)
28px, py = p # unpacking
29
30# When to use tuples
31# - Fixed collections (coordinates, RGB values)
32# - Dictionary keys (since immutable)
33# - Function return values
34# - Faster than lists for iteration

info

Use tuples for data that shouldn't change. Named tuples give you the best of tuples and simple classes — immutability with named fields.
Dictionaries

Dictionaries store key-value mappings. Keys must be hashable (immutable). Insertion order is preserved since Python 3.7.

dicts.py
Python
1# Creation
2empty = {}
3user = {"name": "Alice", "age": 30, "active": True}
4
5# Dict constructor
6dict(name="Bob", age=25) # keyword args
7dict([("a", 1), ("b", 2)]) # from pairs
8{x: x**2 for x in range(3)} # comprehension
9
10# Access
11print(user["name"]) # → Alice (KeyError if missing)
12print(user.get("email")) # → None (safe)
13print(user.get("email", "N/A")) # → N/A with default
14
15# Membership
16print("name" in user) # → True
17print("email" not in user) # → True
18
19# Modification
20user["email"] = "alice@example.com"
21user.update({"age": 31, "city": "NYC"})
22
23# Removal
24del user["active"] # remove key (KeyError if missing)
25user.pop("city") # remove and return value
26user.popitem() # remove and return last inserted (3.7+)
27user.clear() # remove all
28
29# Iteration
30for key in user: # keys
31for value in user.values(): # values
32for k, v in user.items(): # both
33
34# Merging
35d1 = {"a": 1, "b": 2}
36d2 = {"b": 3, "c": 4}
37merged = {**d1, **d2} # spread → {"a": 1, "b": 3, "c": 4}
38merged = d1 | d2 # pipe operator (3.9+)
39
40# Default dict — auto-initialize missing keys
41from collections import defaultdict
42counts = defaultdict(int) # int() gives 0
43counts["a"] += 1
44
45# Counter — count hashable items
46from collections import Counter
47freq = Counter("abracadabra")
48print(freq) # → Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
49print(freq.most_common(2)) # → [('a', 5), ('b', 2)]
Sets

Sets are unordered collections of unique, hashable elements. They support mathematical set operations.

sets.py
Python
1# Creation
2empty = set() # NOT {} — that's a dict
3numbers = {1, 2, 3, 4, 5}
4from_list = set([1, 2, 2, 3]) # → {1, 2, 3} (deduped)
5
6# Set comprehension
7evens = {x for x in range(10) if x % 2 == 0}
8
9# Basic operations
10s = {1, 2, 3}
11s.add(4) # → {1, 2, 3, 4}
12s.remove(4) # → {1, 2, 3} (KeyError if missing)
13s.discard(99) # → {1, 2, 3} (no error if missing)
14s.pop() # remove & return arbitrary element
15s.clear() # remove all
16
17# Membership — O(1) average
18print(2 in {1, 2, 3}) # → True
19
20# Set operations
21a = {1, 2, 3, 4}
22b = {3, 4, 5, 6}
23
24print(a | b) # union → {1, 2, 3, 4, 5, 6}
25print(a & b) # intersection → {3, 4}
26print(a - b) # difference → {1, 2}
27print(a ^ b) # symmetric diff → {1, 2, 5, 6}
28
29# Comparison
30print({1, 2} <= {1, 2, 3}) # subset → True
31print({1, 2, 3} >= {1, 2}) # superset → True
32print({1, 2}.isdisjoint({3, 4})) # → True
33
34# Frozen set — immutable hashable set
35fs = frozenset([1, 2, 3]) # can be dict key or in set

best practice

Use sets for fast membership tests and deduplication. Set operations are significantly faster than list comprehensions for large collections.
Collections Module

The collections module provides specialized data structures beyond the built-ins.

collections_module.py
Python
1from collections import (
2 defaultdict, Counter, namedtuple,
3 deque, OrderedDict, ChainMap
4)
5
6# deque — double-ended queue (fast appends/pops both ends)
7dq = deque([1, 2, 3], maxlen=5)
8dq.append(4) # right
9dq.appendleft(0) # left
10dq.pop() # from right
11dq.popleft() # from left
12
13# OrderedDict — remembers insertion order (dict does this now, but
14# OrderedDict has extra methods like move_to_end)
15od = OrderedDict()
16od["a"] = 1
17od["b"] = 2
18od.move_to_end("a") # move "a" to the end
19
20# ChainMap — combine multiple dicts into one view
21d1 = {"a": 1, "b": 2}
22d2 = {"b": 3, "c": 4}
23chain = ChainMap(d1, d2)
24print(chain["a"]) # → 1 (from d1)
25print(chain["b"]) # → 2 (from d1 — first match wins)
$Blueprint — Engineering Documentation·Section ID: PYTHON-DS·Revision: 1.0