10 Python Data Structures Explained with Examples
Learn when to use Python lists, tuples, dictionaries, sets, deques, heaps and more with runnable examples, trade-offs and troubleshooting.
Which data structure should you use in Python? Use a list for a general ordered collection or a stack, a tuple for a fixed record, a dict for key-based lookup, a set for unique membership, a deque for queues and both-end operations, and heapq when the next item is selected by priority. Python does not define one canonical list of “the ten” data structures; this guide covers ten practical containers and access patterns.
Stack and queue describe access rules rather than separate built-in container classes. A stack is commonly a list; a queue is commonly a collections.deque. A heap-based priority queue is implemented over a regular list by the heapq module.
Quick comparison
| Choice | Best for | Mutable? | Duplicates? | Typical access |
|---|---|---|---|---|
list |
General ordered data, indexing, stacks | Yes | Yes | By position |
tuple |
Fixed records and immutable sequences | No (top level) | Yes | By position |
dict |
Lookup by a meaningful key | Yes | Keys: no; values: yes | By key |
set |
Unique values and membership tests | Yes | No | By membership |
frozenset |
Immutable set values and hashable set keys | No | No | By membership |
array.array |
Homogeneous, type-constrained numeric values | Yes | Yes | By position |
deque |
FIFO queues and both-end operations | Yes | Yes | At either end |
| Stack | Last-in, first-out workflows | Depends on container | Depends on container | Push/pop at one end |
| Queue | First-in, first-out workflows | Depends on container | Depends on container | Append right, remove left |
heapq |
Repeatedly selecting the smallest priority | Yes (list) | Yes | heap[0] is smallest |
1. List: the flexible ordered default
A list is an ordered, mutable sequence. Choose it when you need to append, replace, remove, iterate, or access items by index. It can hold mixed Python objects and repeated values.
scores = [91, 84, 97]
scores.append(88)
scores[1] = 86
print(scores) # [91, 86, 97, 88]
print(scores[0]) # 91
print(scores[-1]) # 88
Lists are also a natural stack because appending and popping at the right end are simple. Avoid repeated insert(0, value) or pop(0) in a busy queue: remaining elements must move, producing O(n) work. The Python tutorial documents this limitation and recommends deque for queues. Python data-structures tutorial.
2. Tuple: an immutable sequence
A tuple is an immutable sequence, useful for a fixed record such as coordinates or a database row. The comma creates a tuple; a one-item tuple needs a trailing comma.
point = (3, 5)
x, y = point
one = ("only",)
print(x, y)
Immutability applies to the tuple’s top-level references. A tuple can contain a mutable object, which can still change. A tuple is hashable only when all of its contents are hashable, so suitable tuples can be dictionary keys or set members.
record = ("Ada", ["python"])
record[1].append("math")
print(record) # ("Ada", ["python", "math"])
locations = {(51.5, -0.1): "London"}
3. Dictionary: lookup by key
A dict maps unique hashable keys to values. Use it when the lookup concept is a name, identifier, or other key rather than a numeric position. Iteration preserves insertion order in modern Python.
prices = {"tea": 3.5, "coffee": 4.0}
prices["tea"] = 3.75
prices["cake"] = 2.5
print(prices.get("juice", 0)) # 0
for item, price in prices.items():
print(item, price)
Indexing a missing key raises KeyError; use get when a default is appropriate. Keys must be hashable, so a list cannot be a key. Values may repeat.
4. Set: unique membership and set operations
A set is a mutable collection of distinct, hashable elements. Use it to remove duplicates, test membership, or calculate unions, intersections, and differences. Sets are unordered; do not rely on iteration order.
tags = set(["python", "data", "python"])
tags.add("algorithms")
print("data" in tags) # True
print(tags | {"testing"}) # union
print(tags & {"python", "web"}) # intersection
empty = set() # {} creates an empty dict
5. Frozenset: an immutable set
frozenset has set membership and set operations but cannot be changed after creation. Because it is immutable and hashable when its elements are hashable, it can itself be a dictionary key or a member of another set.
permissions = frozenset({"read", "write"})
role_by_permissions = {permissions: "editor"}
print("read" in permissions)
Choose it when the collection should not be modified or when a set value must participate in hashing. See Python’s data type index.
6. Array: compact, type-constrained values
array.array is a standard-library sequence for homogeneous values constrained by a type code. It is useful when arbitrary mixed Python objects are unnecessary and you want a specialized numeric sequence. It is not automatically the best choice for every workload.
from array import array
readings = array("i", [4, 8, 12])
readings.append(16)
print(readings[2])
The type code "i" represents a signed integer type supported by the platform. Consult the standard-library data types documentation when selecting a code.
7. Deque: efficient operations at both ends
collections.deque is a double-ended queue. Its appends and pops at either end have approximately O(1) performance, while list operations at the front require moving other elements. Indexing is fast near the ends and slows toward the middle.
from collections import deque
tasks = deque(["a", "b"])
tasks.append("c")
first = tasks.popleft()
tasks.appendleft("urgent")
last = tasks.pop()
print(first, last, tasks)
A bounded deque drops items from the opposite end when it is full:
recent = deque(maxlen=3)
for value in [1, 2, 3, 4]:
recent.append(value)
print(recent) # deque([2, 3, 4], maxlen=3)
Use a list when frequent random indexing matters; use a deque for queues, sliding windows, and both-end work. collections documentation.
8. Stack: last in, first out
A stack is an access pattern, not a separate standard built-in type. A list is usually enough: push with append and pop with pop.
stack = []
stack.append("open file")
stack.append("parse header")
current = stack.pop()
print(current) # parse header
Check before popping if an empty stack is possible, or catch IndexError. For thread coordination, use a queue class from queue rather than treating a plain list as synchronized.
9. Queue: first in, first out
A queue is another access pattern. For a normal in-process FIFO queue, use deque: append on the right and remove on the left. The Python Software Foundation’s tutorial states: “To implement a queue, use collections.deque which was designed to have fast appends and pops from both ends.”
from collections import deque
queue = deque(["first", "second"])
queue.append("third")
next_item = queue.popleft()
print(next_item) # first
For producer and consumer threads, consider the synchronized queue.Queue family. For async programs, use an asyncio queue. The right choice depends on whether you need blocking, thread safety, or awaitable operations.
10. Heap-based priority queue with heapq
Use a heap when the next item should be selected by priority rather than arrival order. The heap invariant guarantees the smallest item is at index zero; it is not a fully sorted list.
import heapq
jobs = [5, 1, 3]
heapq.heapify(jobs) # linear-time transformation
heapq.heappush(jobs, 2)
next_priority = heapq.heappop(jobs)
print(next_priority) # 1
For records, store a priority and a tie-breaker to avoid comparing payload objects:
import heapq
jobs = []
sequence = 0
for priority, name in [(2, "email"), (1, "backup"), (1, "index")]:
heapq.heappush(jobs, (priority, sequence, name))
sequence += 1
while jobs:
priority, _, name = heapq.heappop(jobs)
print(priority, name)
Python 3.14 adds max-heap functions such as heapify_max and heappop_max. On earlier versions, negate numeric priorities or maintain a min-heap of reversed keys. heapq documentation.
How to choose: a practical checklist
- Need ordered, indexable, editable data? Start with
list. - Need a fixed record or hashable compound key? Consider
tuple. - Need lookup by identifier? Use
dict. - Need uniqueness or fast membership? Use
setorfrozenset. - Need homogeneous numeric storage? Evaluate
array.array. - Need append/pop at both ends or FIFO behavior? Use
deque. - Need LIFO behavior? Use a list as a stack.
- Need blocking or async coordination? Use the appropriate queue module.
- Need repeated minimum or priority selection? Use
heapq.
Performance, reliability and cost notes
Choose based on the operation pattern rather than a container’s reputation. Repeated list removal from the front shifts elements; deque end operations are approximately O(1). heapify transforms a list in linear time, while each push or pop maintains the heap invariant. Hash-based lookup and membership require hashable keys or values and depend on well-behaved equality and hashing.
For reliability, define what happens on empty containers (IndexError for list/deque pop), missing dictionary keys (KeyError), and duplicate set inserts (silently ignored). Bound a deque with maxlen only when dropping the oldest or newest data is intentional. Python containers have no external service cost; the practical costs are memory, CPU, and the complexity of converting or copying data.
Troubleshooting common mistakes
| Symptom | Cause | Fix |
|---|---|---|
KeyError |
Dictionary key is absent | Use get, setdefault, or check membership |
TypeError: unhashable type: 'list' |
List used as a dict key or set element | Use a tuple or another immutable, hashable representation |
| Queue becomes slow | pop(0) shifts every remaining list item |
Use deque.popleft() |
| Unexpected set order | Sets are unordered | Sort explicitly when presentation order matters |
IndexError on pop |
Container is empty | Check truthiness or handle the exception |
| Heap output seems unsorted | A heap only guarantees the smallest item at index zero | Pop repeatedly for priority order, or call sorted for a complete ordering |
| Tuple changed unexpectedly | Tuple contains a mutable nested object | Copy or use immutable nested values |
Or skip the browser setup
If your Python data pipeline also needs website screenshots for documentation, regression checks, or visual datasets, ScreenshotNeo provides a single API request instead of maintaining browser drivers. Cookie banners, newsletter popups, and chat widgets are removed before the shot; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots, and the free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.
See the ScreenshotNeo API documentation for all options.
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
Create a free ScreenshotNeo account with 1,000 screenshots per month and no card.
FAQ
What is the difference between a list and a tuple?
A list is mutable; a tuple is immutable at the top level. Both are ordered sequences and can contain duplicates.
How do I make a queue in Python?
Use collections.deque, append new items with append, and remove the oldest with popleft.
Are stack and queue separate Python types?
No. They are access patterns. Lists commonly implement stacks, and deques commonly implement queues.
When should I use a heap instead of sorting?
Use a heap when you repeatedly need the next smallest priority without sorting the entire collection after every insertion.
Can a tuple be a dictionary key?
Yes, if every item inside the tuple is hashable.
Where can I study these structures in more depth?
Wiley lists Data Structures and Algorithms in Python by Michael T. Goodrich, Roberto Tamassia, and Michael H. Goldwasser as a 768-page first-edition hardcover. It is broader than this guide and optional further reading: Wiley product page.


