|$ 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
◆Python◆Beginner 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 |
| 2 | empty = [] |
| 3 | nums = [1, 2, 3, 4, 5] |
| 4 | mixed = [1, "hello", 3.14, True] |
| 5 | nested = [[1, 2], [3, 4, 5]] |
| 6 | |
| 7 | # From other iterables |
| 8 | list("abc") # → ['a', 'b', 'c'] |
| 9 | range(5) # → range(0, 5) (lazy) |
| 10 | list(range(5)) # → [0, 1, 2, 3, 4] |
| 11 | |
| 12 | # Indexing (0-based) |
| 13 | print(nums[0]) # → 1 |
| 14 | print(nums[-1]) # → 5 (last element) |
| 15 | print(nums[-2]) # → 4 (second from last) |
| 16 | |
| 17 | # Slicing [start:stop:step] |
| 18 | print(nums[1:3]) # → [2, 3] |
| 19 | print(nums[:3]) # → [1, 2, 3] |
| 20 | print(nums[::2]) # → [1, 3, 5] |
| 21 | print(nums[::-1]) # → [5, 4, 3, 2, 1] (reversed) |
| 22 | |
| 23 | # Methods |
| 24 | nums.append(6) # add to end → [1,2,3,4,5,6] |
| 25 | nums.extend([7, 8]) # merge → [1,2,3,4,5,6,7,8] |
| 26 | nums.insert(0, 0) # insert at position → [0,1,2,3,4,5,6,7,8] |
| 27 | nums.pop() # remove & return last → 8 |
| 28 | nums.pop(0) # remove & return at index → 0 |
| 29 | nums.remove(3) # remove first occurrence of 3 |
| 30 | nums.clear() # remove all |
| 31 | |
| 32 | # Searching |
| 33 | nums = [1, 2, 3, 2, 4] |
| 34 | print(nums.index(2)) # → 1 (first occurrence) |
| 35 | print(nums.count(2)) # → 2 (how many times) |
| 36 | print(5 in nums) # → False (membership) |
| 37 | |
| 38 | # Ordering |
| 39 | nums.sort() # ascending in-place |
| 40 | nums.sort(reverse=True) # descending in-place |
| 41 | sorted(nums) # returns new sorted list |
| 42 | nums.reverse() # reverse in-place |
| 43 | |
| 44 | # Copying |
| 45 | copy1 = nums.copy() # shallow copy |
| 46 | copy2 = nums[:] # shallow copy via slice |
| 47 | import copy |
| 48 | deep = 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 |
| 2 | empty = () |
| 3 | single = (1,) # trailing comma required! |
| 4 | coords = (10, 20) |
| 5 | named = ("Alice", 30, "Engineer") |
| 6 | |
| 7 | # Parentheses optional (tuple packing) |
| 8 | point = 10, 20 |
| 9 | |
| 10 | # Tuple unpacking (destructuring) |
| 11 | x, y = point |
| 12 | print(x) # → 10 |
| 13 | |
| 14 | # Swapping via tuple |
| 15 | a, b = b, a |
| 16 | |
| 17 | # Unpacking with * |
| 18 | first, *rest = [1, 2, 3, 4] |
| 19 | print(first) # → 1 |
| 20 | print(rest) # → [2, 3, 4] |
| 21 | |
| 22 | # Named tuples (like lightweight objects) |
| 23 | from collections import namedtuple |
| 24 | Point = namedtuple("Point", ["x", "y"]) |
| 25 | p = Point(10, y=20) |
| 26 | print(p.x) # → 10 (attribute access) |
| 27 | print(p[0]) # → 10 (index access) |
| 28 | px, 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 |
| 2 | empty = {} |
| 3 | user = {"name": "Alice", "age": 30, "active": True} |
| 4 | |
| 5 | # Dict constructor |
| 6 | dict(name="Bob", age=25) # keyword args |
| 7 | dict([("a", 1), ("b", 2)]) # from pairs |
| 8 | {x: x**2 for x in range(3)} # comprehension |
| 9 | |
| 10 | # Access |
| 11 | print(user["name"]) # → Alice (KeyError if missing) |
| 12 | print(user.get("email")) # → None (safe) |
| 13 | print(user.get("email", "N/A")) # → N/A with default |
| 14 | |
| 15 | # Membership |
| 16 | print("name" in user) # → True |
| 17 | print("email" not in user) # → True |
| 18 | |
| 19 | # Modification |
| 20 | user["email"] = "alice@example.com" |
| 21 | user.update({"age": 31, "city": "NYC"}) |
| 22 | |
| 23 | # Removal |
| 24 | del user["active"] # remove key (KeyError if missing) |
| 25 | user.pop("city") # remove and return value |
| 26 | user.popitem() # remove and return last inserted (3.7+) |
| 27 | user.clear() # remove all |
| 28 | |
| 29 | # Iteration |
| 30 | for key in user: # keys |
| 31 | for value in user.values(): # values |
| 32 | for k, v in user.items(): # both |
| 33 | |
| 34 | # Merging |
| 35 | d1 = {"a": 1, "b": 2} |
| 36 | d2 = {"b": 3, "c": 4} |
| 37 | merged = {**d1, **d2} # spread → {"a": 1, "b": 3, "c": 4} |
| 38 | merged = d1 | d2 # pipe operator (3.9+) |
| 39 | |
| 40 | # Default dict — auto-initialize missing keys |
| 41 | from collections import defaultdict |
| 42 | counts = defaultdict(int) # int() gives 0 |
| 43 | counts["a"] += 1 |
| 44 | |
| 45 | # Counter — count hashable items |
| 46 | from collections import Counter |
| 47 | freq = Counter("abracadabra") |
| 48 | print(freq) # → Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1}) |
| 49 | print(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 |
| 2 | empty = set() # NOT {} — that's a dict |
| 3 | numbers = {1, 2, 3, 4, 5} |
| 4 | from_list = set([1, 2, 2, 3]) # → {1, 2, 3} (deduped) |
| 5 | |
| 6 | # Set comprehension |
| 7 | evens = {x for x in range(10) if x % 2 == 0} |
| 8 | |
| 9 | # Basic operations |
| 10 | s = {1, 2, 3} |
| 11 | s.add(4) # → {1, 2, 3, 4} |
| 12 | s.remove(4) # → {1, 2, 3} (KeyError if missing) |
| 13 | s.discard(99) # → {1, 2, 3} (no error if missing) |
| 14 | s.pop() # remove & return arbitrary element |
| 15 | s.clear() # remove all |
| 16 | |
| 17 | # Membership — O(1) average |
| 18 | print(2 in {1, 2, 3}) # → True |
| 19 | |
| 20 | # Set operations |
| 21 | a = {1, 2, 3, 4} |
| 22 | b = {3, 4, 5, 6} |
| 23 | |
| 24 | print(a | b) # union → {1, 2, 3, 4, 5, 6} |
| 25 | print(a & b) # intersection → {3, 4} |
| 26 | print(a - b) # difference → {1, 2} |
| 27 | print(a ^ b) # symmetric diff → {1, 2, 5, 6} |
| 28 | |
| 29 | # Comparison |
| 30 | print({1, 2} <= {1, 2, 3}) # subset → True |
| 31 | print({1, 2, 3} >= {1, 2}) # superset → True |
| 32 | print({1, 2}.isdisjoint({3, 4})) # → True |
| 33 | |
| 34 | # Frozen set — immutable hashable set |
| 35 | fs = 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
| 1 | from collections import ( |
| 2 | defaultdict, Counter, namedtuple, |
| 3 | deque, OrderedDict, ChainMap |
| 4 | ) |
| 5 | |
| 6 | # deque — double-ended queue (fast appends/pops both ends) |
| 7 | dq = deque([1, 2, 3], maxlen=5) |
| 8 | dq.append(4) # right |
| 9 | dq.appendleft(0) # left |
| 10 | dq.pop() # from right |
| 11 | dq.popleft() # from left |
| 12 | |
| 13 | # OrderedDict — remembers insertion order (dict does this now, but |
| 14 | # OrderedDict has extra methods like move_to_end) |
| 15 | od = OrderedDict() |
| 16 | od["a"] = 1 |
| 17 | od["b"] = 2 |
| 18 | od.move_to_end("a") # move "a" to the end |
| 19 | |
| 20 | # ChainMap — combine multiple dicts into one view |
| 21 | d1 = {"a": 1, "b": 2} |
| 22 | d2 = {"b": 3, "c": 4} |
| 23 | chain = ChainMap(d1, d2) |
| 24 | print(chain["a"]) # → 1 (from d1) |
| 25 | print(chain["b"]) # → 2 (from d1 — first match wins) |
$Blueprint — Engineering Documentation·Section ID: PYTHON-DS·Revision: 1.0