Data Structures Basics
9 examples to get you started with Python's built-in containers - 6 basic and 3 intermediate.
Prerequisites
- Python 3.14.0 and familiarity with Python Basics.
Basic Examples
1. List - Ordered Mutable Sequence
Append, index, and slice sequences.
items = ["a", "b", "c"]
items.append("d")
first = items[0]
middle = items[1:3]- O(1) append at end; O(n) insert at front.
- Lists are heterogeneous - any object types allowed.
- Slicing returns a new list (shallow copy of references).
Related: Lists & Tuples - sorting and bisect
2. Tuple - Fixed Immutable Sequence
Pack related values that should not change.
point = (10, 20)
x, y = point
record = ("ada", 1842)- Tuples are hashable when all elements are hashable.
- Single-element tuple needs trailing comma:
(42,). - Unpacking works in assignments and
forloops.
Related: Immutability & Hashability - when tuples are dict keys
3. dict - Key-Value Mapping
Fast lookup by hashable key.
user = {"id": 1, "name": "Ada"}
user["email"] = "ada@example.com"
for key, value in user.items():
print(key, value)- Average O(1) get/set/delete by key.
- Insertion order preserved (language guarantee since 3.7).
- Keys must be hashable - no mutable lists as keys.
Related: Dictionaries - merging and views
4. set - Unique Unordered Collection
Membership and set algebra.
tags = {"python", "data", "python"}
tags.add("ml")
assert "data" in tags
common = {"a", "b"} & {"b", "c"} # {"b"}- Literals use
{}only for dicts - sets needset()or{"x"}with values. - Average O(1)
intests - great for deduplication checks. - Union/intersection/difference via operators
|,&,-.
Related: Sets & Frozensets - frozenset as dict key
5. Big-O Cheat Sheet
| Operation | list | dict | set |
|---|---|---|---|
| Index i | O(1) | - | - |
| Membership | O(n) | O(1)* | O(1)* |
| Append | O(1)* | - | - |
| Insert middle | O(n) | - | - |
*Average case; worst-case hash collisions degrade dict/set.
- Choose
set/dictwhen you need fast membership. - Choose
listwhen order and duplicates matter with index access. - Profile hot paths - constants matter for small n.
Related: Choosing the Right Data Structure - decision guide
6. collections.deque for Queues
Fast append/pop from both ends.
from collections import deque
queue: deque[str] = deque()
queue.append("job-1")
queue.append("job-2")
next_job = queue.popleft()list.pop(0)is O(n);deque.popleft()is O(1).- Optional
maxlendrops oldest items automatically. - Not a priority queue - use
heapqfor ordering by priority.
Related: collections Module - Counter and defaultdict
Intermediate Examples
7. defaultdict for Grouping
Avoid manual key-exists checks when building groups.
from collections import defaultdict
by_role: defaultdict[str, list[str]] = defaultdict(list)
for name, role in [("Ada", "admin"), ("Linus", "dev"), ("Guido", "dev")]:
by_role[role].append(name)- Factory runs only on missing keys.
- Still a dict - same iteration and serialization patterns.
- Prefer over
setdefaultwhen the default is a fresh mutable.
Related: collections Module - full API tour
8. Counter for Frequencies
Count hashable items in one pass.
from collections import Counter
words = ["a", "b", "a", "c", "a", "b"]
counts = Counter(words)
print(counts.most_common(2)) # [('a', 3), ('b', 2)]- Subtract counters for multiset diffs.
elements()expands counts back to repeated items.- Great for log analysis and histogram sketches.
9. Named Tuple for Lightweight Records
Readable field access without a full class.
from typing import NamedTuple
class Point(NamedTuple):
x: int
y: int
p = Point(3, 4)
print(p.x, p.y)- Immutable - safe as dict keys when fields are hashable.
dataclassis often better when you need defaults or methods.TypedDictfits JSON-shaped dicts that stay dicts at runtime.
Related: TypedDict & NamedTuple - typing records
Stack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.