Lists and Dictionaries

How to store data in Python without regretting it later — the standard containers.

Fundamentals 13 min Beginner April 26, 2026

So far, every variable you have created holds exactly one value — a number, a string, a boolean. But real programs deal with collections: a list of 1,000 student names, a user profile with name, age, and city, or an API response with hundreds of data points. Managing 1,000 separate variables is like keeping 1,000 loose sticky notes instead of one organized notebook.

Python provides two fundamental collection types: lists for ordered sequences (when position matters) and dictionaries for key-value pairs (when you want to look things up by name). These two structures are so central that nearly every Python program uses at least one of them.

Lists — Ordered Collections with Numbered Slots

List (list)

AnalogyDefinition
A list is like a numbered shelf in a workshop. Each slot has a number starting from 0 — Slot 0, Slot 1, Slot 2. You can put any item in any slot, add new slots at the end (append), remove a slot and shift everything after it (pop), or insert a new slot in the middle (insert). To find something, you either know its slot number (index access) or scan all slots (the in operator).

The shelf analogy fits well for numbered positions and shifting during insert/remove. It breaks because a real shelf has a fixed number of slots — Python lists grow dynamically. Also, shelf slots have physical size constraints, while Python lists can hold any object, including other lists.

Shopping List Step by Step

1
shopping = ["Bread", "Milk", "Apples"] → 3 items at positions 0, 1, 2
2
shopping.append("Cheese") → 4 items: [..., "Cheese"] at position 3
3
print(shopping[0]) → "Bread" (first item = index 0)
4
shopping.pop(1) → removes "Milk", list: ["Bread", "Apples", "Cheese"]
5
"Milk" in shopping → False (it was removed)

Each step shows the list state after the operation. Notice: after pop(1), all elements to the right shift one position to the left.

Watch Out: IndexError

The index must be between 0 and len(list) - 1. Accessing beyond these bounds raises an IndexError. Because Python starts at 0, list[3] is the fourth element — not the third.

colors = ["red", "green", "blue"]
print(colors[3])   # IndexError: list index out of range
# Valid indices: 0, 1, 2

Dictionaries — Looking Things Up by Name

Dictionary (dict)

AnalogyDefinition
A dictionary is like a phone book. You don't look up "the 47th entry" — you look up a name (the key) to find the phone number (the value). The phone book guarantees each name appears only once (unique keys), and looking up a name is fast regardless of how thick the book is. If you search for a name that isn't listed, you get an error (KeyError) — or use .get(): "Do you have Max Mueller? If not, just say 'unknown'."

The phone book analogy fits for key-based access and uniqueness. It breaks because a real phone book is alphabetically sorted — Python dicts use hash tables, not alphabetical order. Also, a phone book contains only name-number pairs, while Python dicts can map any immutable key to any value, including nested dicts and lists.

Example: Person Record

person = {"name": "Anna", "age": 28, "city": "Berlin"}

print(person["age"])                       # 28
person["job"] = "Engineer"                  # adds new key-value pair
print(person.get("hobby", "unknown"))       # "unknown" (no error)

for key, value in person.items():
    print(f"{key}: {value}")                # prints all pairs

The .get() call is the safe counterpart to person["hobby"], which would crash with KeyError. Use .get() whenever you're not sure a key exists.

List

Ordered sequence. Access by index (position). Use lists when order matters: shopping lists, step sequences, collections you iterate through.

Dictionary

Key-value mapping. Access by key (name). Use dicts when you want to look things up by name: user profiles, configurations, word counters.

Watch Out: KeyError

Accessing dict[key] with a non-existent key raises a KeyError. Use .get(key, default) instead for safe access.

person = {"name": "Anna"}
print(person["hobby"])                      # KeyError: 'hobby'
print(person.get("hobby", "unknown"))       # "unknown" (no error)

Aliasing — When Two Names Share One Object

Aliasing

AnalogyDefinition
Aliasing is like a shared online document. Imagine you and a colleague both have a link to the same Google Doc. If your colleague edits a paragraph, you see the change immediately — because you're both looking at the same document, not separate copies. Creating a copy with a.copy() is like clicking "Make a copy" in Google Docs — now each of you has your own independent version.

The document analogy fits for "two links, one object." It breaks because in real life, sharing a document is a deliberate choice (you send a link), while aliasing in Python happens automatically and silently when you write b = a. Beginners don't realize they're "sharing" the object.

The Aliasing Trap Step by Step

1
a = [1, 2, 3] → List with three elements created
2
b = a → b is an alias, NOT a copy! Both point to the same list.
3
b.append(4) → The list is now [1, 2, 3, 4]
4
print(a) → [1, 2, 3, 4] — a changed too! Fix: b = a.copy()

Aliasing Is Silent and Automatic

b = a does NOT copy. It creates a second name for the same object. Always use .copy() for an independent copy. This applies to lists AND dictionaries.

# Alias (NOT copied):
b = a
b.append(4)    # also changes a!

# Real copy:
b = a.copy()
b.append(4)    # a stays unchanged
List Ordered sequence with numbered positions (starting at 0)
Dictionary Key-value mapping for fast lookups
IndexError Accessing a position beyond the list length
KeyError Accessing a key that doesn't exist in the dictionary

Interactive: Python Collection Types Compared

You now know lists and dictionaries. But Python has two more collection types: sets and tuples. Click on a row in the comparison matrix to see the properties and typical use cases of each type. Pay attention to the color coding: green indicates available capabilities, red indicates limitations.

Python Collection Types Compared

Advantage (small/fast/high)
Neutral
Disadvantage (large/slow/low)

Click a row for detail view

TypeOrderedMutableDuplicatesAccess
list Index [i]
dict ✗ Keys Key ["k"]
set
tuple Index [i]
Key Takeaway: Choosing the right collection type depends on three questions: Do you need a specific order? Should the collection be mutable? Must elements be unique? The matrix shows at a glance which type meets which requirements.

Guido van Rossum, Python's creator, explained the decision in a 2013 blog post: half-open intervals like a[:n] for the first n elements and a[n:] for the rest work cleanly with 0-based indices, without fiddly +1/-1 corrections. This design comes from the C tradition that heavily influenced Python.

A practical benefit: len(list) is always the first invalid index — making boundary checks easy.

JSON (JavaScript Object Notation) is the standard format for web APIs, AI model configurations, and data exchange. When loaded with json.loads(), JSON objects become Python dicts and JSON arrays become Python lists.

import json

api_response = '{"name": "GPT-4", "type": "LLM", "params": [175, "billion"]}'
data = json.loads(api_response)

print(data["name"])       # "GPT-4" (dict access)
print(data["params"][0])  # 175 (nested: dict → list)

Understanding lists and dictionaries means understanding the structure of real-world data — from API responses to configuration files.

Key Takeaways

  1. A list is an ordered, mutable sequence accessed by index (starting at 0). Use lists when order matters — shopping lists, step sequences, collections you iterate through.
  2. A dictionary is a mutable collection of key-value pairs accessed by key. Use dicts when you want to look things up by name — user profiles, configurations, word counters.
  3. b = a does not copy a list or dictionary — it creates a second name for the same object. Use a.copy() or list(a) for an independent copy.
  4. Common traps: IndexError (accessing beyond list length), KeyError (accessing a missing dict key — use .get()), off-by-one errors from 0-based indexing.
  5. JSON — the format for web APIs and AI services — maps directly to Python dictionaries and lists. Understanding these two types means understanding the shape of real-world data.

Quiz: Lists and Dictionaries

Question 1 / 4
Not completed

What does colors[1] return if colors = ["red", "green", "blue"]?

Select one answer
Answer Key: 1) B · 2) C · 3) B · 4) B

Checkpoint: Do You Understand Lists and Dictionaries?

  • You have the list colors = ["red", "green", "blue"]. What does colors[1] return? And what happens with colors[5]?
  • You have person = {"name": "Anna"}. What's the difference between person["hobby"] and person.get("hobby", "unknown")?
  • You write b = a and then change b. Why does a change too? How do you prevent this?