# 04 - Dictionaries
**Notebook:** `04-dictionaries.ipynb`
## Video
<iframe width="720" height="406" src="https://www.youtube.com/embed/YzDZFWQhPeA?si=jq0oAUeFt6tswroh" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
---
## More Complex Data Structures
Up till now, in our variables we've held pretty simple things—like the title of one poem, or maybe a list of titles. But most of the data we work with in the world is actually more complex than just a title.
A [**dictionary**](/glossary/coding-basics-py/dictionary) is going to help us with that. It allows us to have a more complex data structure for all of the things we want to operate on.
A poem—especially for the encyclopedia assignment we're about to do—has a bunch of different properties. And what we're going to do in Python is store those in a dictionary.
---
## Creating a Dictionary
Dictionaries are going to look similar to lists in some ways—there's brackets around stuff and then a bunch of things inside. But here we're going to use **curly brackets** `{}` instead of square brackets:
```python
poem = {
"title": "The Raven",
"author": "Edgar Allan Poe",
"year": 1845,
"bird": "raven"
}
print(poem)
```
Within the curly brackets, we have:
- **Keys** (or attributes) — names for a property (like `"title"`, `"author"`)
- **Values** — what belongs to that property (like `"The Raven"`, `"Edgar Allan Poe"`)
Instead of an equals sign like when we assign a variable, inside a dictionary we use a **colon** to assign a value to a key.
You can almost think of these as little variables that you're setting up within something larger. A poem is sort of like an **object** that has properties, and we're defining each of those properties.
I put them on separate lines because it's easier to read that way, but they don't need to be on separate lines.
---
## Accessing Properties
Just as was the case with lists, if you want to get a specific property, you use similar syntax. But this is actually **much more common** than going and grabbing element seven of a list. This is something you are going to do **all the time**.
```python
print(poem["title"]) # The Raven
print(poem["author"]) # Edgar Allan Poe
print(poem["bird"]) # raven
```
The syntax: the name of the dictionary, then square brackets, then the name of the property (in quotes).
When there's a particular property of something you have, you are very frequently going to be trying to get that property for a specific purpose—like getting the title to display, or the author for a citation.
---
## Adding New Properties
You can add a new key to an existing dictionary (or update an existing one):
```python
poem["themes"] = ["death", "loss", "memory"]
```
Now the dictionary has a `themes` property too.
---
## Lists of Dictionaries
What's cool is that you can put **dictionaries within lists** and **lists within dictionaries**. This can get very, very complicated, but this is precisely what we're going to do.
Because what we're going to have is a list of poems, and that list is not just going to be a list of titles—it's going to be a **list of dictionaries**. Each poem will be one of these curly brace packages that has a title, an author, name of the bird, an image path, a description, etc.
```python
poems = [
{"title": "The Raven", "bird": "raven"},
{"title": "Ode to a Nightingale", "bird": "nightingale"},
{"title": "The Windhover", "bird": "falcon"},
]
for p in poems:
print(f"{p['title']} features a {p['bird']}")
```
**Note:** We use single quotes `'title'` inside the f-string because the f-string itself uses double quotes. You can't nest the same quote type.
Output:
```text
The Raven features a raven
Ode to a Nightingale features a nightingale
The Windhover features a falcon
```
This is something you're going to encounter a lot as you look through the code you get and the results of the code you get.
---
## Nesting
In a dictionary, we can have as many properties as we want. They can also be **nested**. If this wasn't poems but authors, you could have a list of authors, and then there could be a property called `works` that could itself be a list of works.
These things really can nest and get quite complicated. But don't worry—we'll build up to it.
---
## A Note on "Objects" vs "Dictionaries"
I might accidentally call these **objects**—I apologize if that ever happens. It's just because in JavaScript, that's the more typical way of thinking about this.
Don't stress. If I say "objects," just know I mean dictionaries. And if you're someone coming from JavaScript, now you know this difference.
---
## Why This Matters for the Encyclopedia
For our encyclopedia, we want something like a spreadsheet:
- A **row** for every poem
- Every poem has the same **columns**: title, text, author, date, bird name, interpretation, image prompt, etc.
A list of dictionaries is exactly this structure. Each dictionary is a row, and each key is a column.
---
## Try It
1. Create a brand new dictionary for a new poem
2. Add at least 4 properties (title, author, year, and something else)
3. Try accessing each property individually
4. Create a list with 2-3 poem dictionaries and loop through them
---
## Summary
In this notebook, you learned:
- A **dictionary** stores key-value pairs in curly braces `{}`
- Access values with `dictionary["key"]` syntax
- Dictionaries can hold different types of values (strings, numbers, even lists!)
- **Lists of dictionaries** are a powerful pattern for structured data
- This is the structure we'll use for our encyclopedia entries
Next up: **functions** — reusable code!