Dictionaries & JSON
What You'll Build Today
Welcome to Day 6. Today is a pivotal day. Up until now, we have been storing data in lists. Lists are great for keeping items in a specific order, like a to-do list or a queue of songs. But lists are terrible at relationships.
Today, we are going to build a Digital Contact Book. By the end of this session, you will build an application that can store a person's name, email, phone number, and even their location, all organized so you can find exactly what you need instantly without searching through the whole pile.
Here is what you will learn and, more importantly, why:
* Dictionaries (Key-Value Pairs): You will learn to label your data. Instead of remembering that the email is at "index 1," you will just ask for the "email."
* Nested Dictionaries: Real data is rarely flat. You will learn to store data inside other data, which is exactly how complex information is structured in the real world.
* The .get() Method: You will learn how to write safe code that doesn't crash when information is missing.
* JSON (JavaScript Object Notation): This is the universal language of the internet. When you eventually ask an AI model a question, the answer comes back in this format. If you can't navigate it, you can't use the AI's response.
Let's get started.
The Problem
Imagine you are trying to store contact information for three people using what we have learned so far (variables and lists).
You might try creating a list for names and a separate list for emails.
# The "List" approach
names = ["Alice", "Bob", "Charlie"]
emails = ["alice@tech.com", "bob@design.com", "charlie@sales.com"]
phone_numbers = ["555-0100", "555-0101", "555-0102"]
# I want to find Bob's email.
# First, I have to find where Bob is in the names list.
# I happen to know he is second, so that is index 1.
bobs_index = 1
print(f"Name: {names[bobs_index]}")
print(f"Email: {emails[bobs_index]}")
print(f"Phone: {phone_numbers[bobs_index]}")
This works, technically. But think about the problems here:
names list but forget to delete her from emails and phone_numbers, everything shifts. Suddenly, "Bob" (now at index 0) has Alice's email. Your data is corrupted. # A list of lists?
contacts = [
["Alice", "alice@tech.com", "555-0100"],
["Bob", "bob@design.com", "555-0101"]
]
# To get Bob's phone number:
print(contacts[1][2])
Look at contacts[1][2]. What does 2 mean? Is it the phone number? The zip code? The age? You have to memorize the structure. If you hand this code to a colleague, they will have no idea what index 2 represents.
There has to be a way to label data so we can say: "Give me Bob's email," rather than "Give me the item at index 1."
Let's Build It
The solution is the Dictionary.
In Python, a dictionary is a collection of Key-Value pairs. Think of a real physical dictionary. You don't read it page by page to find a definition. You look up a specific word (the Key) to find its definition (the Value).
Step 1: Creating a Simple Dictionary
We use curly braces {} for dictionaries. Keys and values are separated by a colon :.
# Creating a dictionary for a single person
# Key : Value
person = {
"name": "Alice",
"email": "alice@tech.com",
"role": "Developer"
}
print(person)
print(type(person))
Output:
{'name': 'Alice', 'email': 'alice@tech.com', 'role': 'Developer'}
Step 2: Accessing Data (The Unsafe vs. Safe Way)
To get data out, we use the key name.
person = {
"name": "Alice",
"email": "alice@tech.com",
"role": "Developer"
}
# 1. The Bracket Method (Direct Access)
print(person["name"])
print(person["email"])
# 2. The Pain of Brackets
# Uncommenting the line below causes a crash because "phone" doesn't exist yet
# print(person["phone"])
# KeyError: 'phone'
If you try to access a key that doesn't exist using brackets [], Python throws an error and stops your program. This is dangerous when working with AI or web data, because sometimes data is missing.
.get()
# 3. The .get() Method (Safe Access)
print(person.get("email"))
# If the key doesn't exist, .get() returns None instead of crashing
print(person.get("phone"))
# You can even provide a default value if the key is missing
print(person.get("phone", "No phone number found"))
Output:
Alice
alice@tech.com
alice@tech.com
None
No phone number found
Step 3: Adding and Modifying Data
Dictionaries are mutable (changeable). You can add new keys or update existing ones just by assigning them.
person = {
"name": "Alice",
"role": "Developer"
}
print(f"Original: {person}")
# Adding a new key-value pair
person["email"] = "alice@new-job.com"
# Updating an existing key
person["role"] = "Senior Developer"
print(f"Updated: {person}")
Output:
Original: {'name': 'Alice', 'role': 'Developer'}
Updated: {'name': 'Alice', 'role': 'Senior Developer', 'email': 'alice@new-job.com'}
Step 4: The Contact Book (Nested Dictionaries)
Now, let's solve the original problem. We want to store multiple people. We can use a dictionary where the Key is the person's name, and the Value is another dictionary containing their details.
This is called Nesting.
contacts = {
"Alice": {
"phone": "555-0100",
"email": "alice@tech.com"
},
"Bob": {
"phone": "555-0101",
"email": "bob@design.com"
}
}
# Accessing nested data
# Logic: Go into 'contacts', find 'Alice', then find 'phone'
alice_phone = contacts["Alice"]["phone"]
print(f"Alice's phone is: {alice_phone}")
Output:
Alice's phone is: 555-0100
Step 5: Iterating Through Dictionaries
Sometimes you want to list everyone in your book. You can loop through keys, values, or both.
contacts = {
"Alice": {"email": "alice@tech.com"},
"Bob": {"email": "bob@design.com"},
"Charlie": {"email": "charlie@sales.com"}
}
print("--- Contact List ---")
# .items() gives us both the key (name) and value (info_dict)
for name, info in contacts.items():
email = info["email"]
print(f"Name: {name} | Email: {email}")
Output:
--- Contact List ---
Name: Alice | Email: alice@tech.com
Name: Bob | Email: bob@design.com
Name: Charlie | Email: charlie@sales.com
Step 6: Introduction to JSON
This is the bridge to AI. JSON (JavaScript Object Notation) looks almost exactly like a Python dictionary. It is the standard format for sending data across the web.
When you use Python to talk to OpenAI or Google Gemini, you send JSON, and they send JSON back.
Python has a built-in tool to handle this.
import json
# A Python Dictionary
my_data = {
"name": "Alice",
"is_student": False,
"skills": ["Python", "AI", "Data"]
}
# 1. dumps (Dump to String): Convert Dictionary -> JSON String
# We use this when SENDING data to an AI
json_string = json.dumps(my_data)
print(f"Type: {type(json_string)}")
print(f"Data: {json_string}")
# 2. loads (Load from String): Convert JSON String -> Dictionary
# We use this when RECEIVING data from an AI
incoming_data = '{"id": 101, "status": "success"}'
parsed_data = json.loads(incoming_data)
print(f"Type: {type(parsed_data)}")
print(f"Status is: {parsed_data['status']}")
Output:
Type:
Data: {"name": "Alice", "is_student": false, "skills": ["Python", "AI", "Data"]}
Type:
Status is: success
Note: In JSON, False becomes false (lowercase). Python handles this conversion for you automatically.
Now You Try
You have the source code for the Contact Book above. Now, extend it.
contacts dictionary so that every person also has a "city" key.input()) for a name. * If the name exists in contacts, print their email and city.
* If the name does not exist, print "User not found" (Hint: Use the in keyword or .get()).
Challenge Project: The API Parser
When you work with AI, you will often receive a large, complex "response object" that contains the answer you want, buried inside metadata.
Your challenge is to extract specific data from a mock API response representing a social media post.
Requirements:api_response variable provided below into your code.api_response = {
"status": 200,
"data": {
"post_id": "8823-1123",
"content": "Just learned about Python dictionaries! #coding #python #learning",
"metrics": {
"likes": 42,
"shares": 12,
"views": 1500
},
"author": {
"username": "coder_jane",
"display_name": "Jane Doe",
"is_verified": True,
"profile": {
"age": 28,
"location": "San Francisco"
}
}
}
}
Expected Output:
Author: coder_jane
Likes: 42
Hashtag: #python
Verified Account
Hints:
* This is a dictionary inside a dictionary inside a dictionary.
* To get the username, you need to go: api_response -> data -> author -> username.
* The hashtags are inside the string "content". You might need to manipulate that string or just manually locate the second one if you haven't learned string splitting yet (though string splitting content.split() is the best way!).
What You Learned
Today you moved from simple lists to structured data.
* Dictionaries: You can now label data with keys (name, email) instead of relying on numbered indexes.
* Nesting: You learned that values can be other dictionaries, allowing you to model complex real-world objects.
* Safety: You learned to use .get() to prevent your code from crashing when data is missing.
* JSON: You learned that JSON is just a text representation of a dictionary, used for web communication.
Why This Matters:In Phase 2, you will build a chatbot. The conversation history of that chatbot will be a list of dictionaries:
[{"role": "user", "content": "Hello"}, {"role": "ai", "content": "Hi there!"}]
Understanding today's lesson is the only way you will be able to build that history.
Tomorrow: We tackle Functions. You have been writing a lot of code that runs top-to-bottom. Tomorrow, we will learn how to package that code into reusable blocks so you don't have to repeat yourself.