Nesting in Python Dictionary

Sometimes you’ll want to store multiple dictionaries in a list, or a list of items as a value in a dictionary. This is called nesting. You can nest dictionaries inside a list, a list of items inside a dictionary, or even a dictionary inside another dictionary. Nesting is a powerful feature, as the following examples will demonstrate.

A List of Dictionaries

The alien_0 dictionary contains a variety of information about one alien, but it has no room to store information about a second alien, much less a screen full of aliens. How can you manage a fleet of aliens? One way is to make a list of aliens in which each alien is a dictionary of information about that alien. For example, the following code builds a list of three aliens:

aliens.py

   alien_0 = {'color': 'green', 'points': 5}
   alien_1 = {'color': 'yellow', 'points': 10}
   alien_2 = {'color': 'red', 'points': 15}

➊ aliens = [alien_0, alien_1, alien_2]

   for alien in aliens:
       print(alien)

We first create three dictionaries, each representing a different alien. At ➊ we store each of these dictionaries in a list called aliens. Finally, we loop through the list and print out each alien:

{‘color’: ‘green’, ‘points’: 5}
{‘color’: ‘yellow’, ‘points’: 10}
{‘color’: ‘red’, ‘points’: 15}

A more realistic example would involve more than three aliens with code that automatically generates each alien. In the following example we use range() to create a fleet of 30 aliens:

   # Make an empty list for storing aliens.
   aliens = []

   # Make 30 green aliens.
➊ for alien_number in range(30):
➋     new_alien = {‘color’: ‘green’, ‘points’: 5, ‘speed’: ‘slow’}
➌     aliens.append(new_alien)

   # Show the first 5 aliens.
➍ for alien in aliens[:5]:
       print(alien)
   print(“…”)

   # Show how many aliens have been created.
➎ print(f”Total number of aliens: {len(aliens)}”)

This example begins with an empty list to hold all of the aliens that will be created. At ➊ range() returns a series of numbers, which just tells Python how many times we want the loop to repeat. Each time the loop runs we create a new alien ➋ and then append each new alien to the list aliens ➌. At ➍ we use a slice to print the first five aliens, and then at ➎ we print the length of the list to prove we’ve actually generated the full fleet of 30 aliens:

{‘color’: ‘green’, ‘points’: 5, ‘speed’: ‘slow’}
{‘color’: ‘green’, ‘points’: 5, ‘speed’: ‘slow’}
{‘color’: ‘green’, ‘points’: 5, ‘speed’: ‘slow’}
{‘color’: ‘green’, ‘points’: 5, ‘speed’: ‘slow’}
{‘color’: ‘green’, ‘points’: 5, ‘speed’: ‘slow’}


Total number of aliens: 30

These aliens all have the same characteristics, but Python considers each one a separate object, which allows us to modify each alien individually.

How might you work with a group of aliens like this? Imagine that one aspect of a game has some aliens changing color and moving faster as the game progresses. When it’s time to change colors, we can use a for loop and an if statement to change the color of aliens. For example, to change the first three aliens to yellow, medium-speed aliens worth 10 points each, we could do this:

# Make an empty list for storing aliens.
aliens = []

# Make 30 green aliens.
for alien_number in range (30):
    new_alien = {‘color’: ‘green’, ‘points’: 5, ‘speed’: ‘slow’}
    aliens.append(new_alien)

for alien in aliens[:3]:
    if alien[‘color’] == ‘green’:
        alien[‘color’] = ‘yellow’
        alien[‘speed’] = ‘medium’
        alien[‘points’] = 10

# Show the first 5 aliens.
for alien in aliens[:5]:
    print(alien)
print(“…”)

Because we want to modify the first three aliens, we loop through a slice that includes only the first three aliens. All of the aliens are green now but that won’t always be the case, so we write an if statement to make sure we’re only modifying green aliens. If the alien is green, we change the color to ‘yellow’, the speed to ‘medium’, and the point value to 10, as shown in the following output:

{‘color’: ‘yellow’, ‘points’: 10, ‘speed’: ‘medium’}
{‘color’: ‘yellow’, ‘points’: 10, ‘speed’: ‘medium’}
{‘color’: ‘yellow’, ‘points’: 10, ‘speed’: ‘medium’}
{‘color’: ‘green’, ‘points’: 5, ‘speed’: ‘slow’}
{‘color’: ‘green’, ‘points’: 5, ‘speed’: ‘slow’}

You could expand this loop by adding an elif block that turns yellow aliens into red, fast-moving ones worth 15 points each. Without showing the entire program again, that loop would look like this:

for alien in aliens[0:3]:
    if alien[‘color’] == ‘green’:
        alien[‘color’] = ‘yellow’
        alien[‘speed’] = ‘medium’
        alien[‘points’] = 10
    elif alien[‘color’] == ‘yellow’:
        alien[‘color’] = ‘red’
        alien[‘speed’] = ‘fast’
        alien[‘points’] = 15

It’s common to store a number of dictionaries in a list when each dictionary contains many kinds of information about one object. For example, you might create a dictionary for each user on a website, and store the individual dictionaries in a list called users. All of the dictionaries in the list should have an identical structure so you can loop through the list and work with each dictionary object in the same way.

A List in a Dictionary

Rather than putting a dictionary inside a list, it’s sometimes useful to put a list inside a dictionary. For example, consider how you might describe a pizza that someone is ordering. If you were to use only a list, all you could really store is a list of the pizza’s toppings. With a dictionary, a list of toppings can be just one aspect of the pizza you’re describing.

In the following example, two kinds of information are stored for each pizza: a type of crust and a list of toppings. The list of toppings is a value associated with the key ‘toppings’. To use the items in the list, we give the name of the dictionary and the key ‘toppings’, as we would any value in the dictionary. Instead of returning a single value, we get a list of toppings:

pizza.py

   # Store information about a pizza being ordered.
➊ pizza = {
       'crust': 'thick',
       'toppings': ['mushrooms', 'extra cheese'],
       }
   # Summarize the order.
➋ print(f"You ordered a {pizza['crust']}-crust pizza "
       "with the following toppings:")

➌ for topping in pizza['toppings']:
       print(f"\t{topping}")

We begin at ➊ with a dictionary that holds information about a pizza that has been ordered. One key in the dictionary is ‘crust’, and the associated value is the string ‘thick’. The next key, ‘toppings’, has a list as its value that stores all requested toppings. At ➋ we summarize the order before building the pizza. When you need to break up a long line in a print() call, choose an appropriate point at which to break the line being printed, and end the line with a quotation mark. Indent the next line, add an opening quotation mark, and continue the string. Python will automatically combine all of the strings it finds inside the parentheses. To print the toppings, we write a for loop ➌. To access the list of toppings, we use the key ‘toppings’, and Python grabs the list of toppings from the dictionary.

The following output summarizes the pizza that we plan to build:

You ordered a thick-crust pizza with the following toppings:
    mushrooms
    extra cheese

You can nest a list inside a dictionary any time you want more than one value to be associated with a single key in a dictionary. In the earlier example of favorite programming languages, if we were to store each person’s responses in a list, people could choose more than one favorite language. When we loop through the dictionary, the value associated with each person would be a list of languages rather than a single language. Inside the dictionary’s for loop, we use another for loop to run through the list of languages associated with each person:

favorite_languages.py

➊ favorite_languages = {
       'jen': ['python', 'ruby'],
       'sarah': ['c'],
       'edward': ['ruby', 'go'],
       'phil': ['python', 'haskell'],
       }

➋ for name, languages in favorite_languages.items():
       print(f"\n{name.title()}'s favorite languages are:")
➌     for language in languages:
           print(f"\t{language.title()}")

As you can see at ➊ the value associated with each name is now a list. Notice that some people have one favorite language and others have multiple favorites. When we loop through the dictionary at ➋, we use the variable name languages to hold each value from the dictionary, because we know that each value will be a list. Inside the main dictionary loop, we use another for loop ➌ to run through each person’s list of favorite languages. Now each person can list as many favorite languages as they like:

Jen’s favorite languages are:
    Python
    Ruby

Sarah’s favorite languages are:
    C

Edward’s favorite languages are:
    Ruby
    Go

Phil’s favorite languages are:
    Python
    Haskell

To refine this program even further, you could include an if statement at the beginning of the dictionary’s for loop to see whether each person has more than one favorite language by examining the value of len(languages). If a person has more than one favorite, the output would stay the same. If the person has only one favorite language, you could change the wording to reflect that. For example, you could say Sarah’s favorite language is C.

NOTE

You should not nest lists and dictionaries too deeply. If you’re nesting items much deeper than what you see in the preceding examples or you’re working with someone else’s code with significant levels of nesting, most likely a simpler way to solve the problem exists.

A Dictionary in a Dictionary

You can nest a dictionary inside another dictionary, but your code can get complicated quickly when you do. For example, if you have several users for a website, each with a unique username, you can use the usernames as the keys in a dictionary. You can then store information about each user by using a dictionary as the value associated with their username. In the following listing, we store three pieces of information about each user: their first name, last name, and location. We’ll access this information by looping through the usernames and the dictionary of information associated with each username:

many_users.py

   users = {
       'aeinstein': {
           'first': 'albert',
           'last': 'einstein',
           'location': 'princeton',
           },

       'mcurie': {
           'first': 'marie',
           'last': 'curie',
           'location': 'paris',
           },
       }

➊ for username, user_info in users.items():
➋     print(f"\nUsername: {username}")
➌     full_name = f"{user_info['first']} {user_info['last']}"
       location = user_info['location']

➍     print(f"\tFull name: {full_name.title()}")
       print(f"\tLocation: {location.title()}")

We first define a dictionary called users with two keys: one each for the usernames ‘aeinstein’ and ‘mcurie’. The value associated with each key is a dictionary that includes each user’s first name, last name, and location. At ➊ we loop through the users dictionary. Python assigns each key to the variable username, and the dictionary associated with each username is assigned to the variable user_info. Once inside the main dictionary loop, we print the username at ➋.

At ➌ we start accessing the inner dictionary. The variable user_info, which contains the dictionary of user information, has three keys: ‘first’, ‘last’, and ‘location’. We use each key to generate a neatly formatted full name and location for each person, and then print a summary of what we know about each user ➍:

Username: aeinstein
    Full name: Albert Einstein
    Location: Princeton

Username: mcurie
    Full name: Marie Curie
    Location: Paris

Notice that the structure of each user’s dictionary is identical. Although not required by Python, this structure makes nested dictionaries easier to work with. If each user’s dictionary had different keys, the code inside the for loop would be more complicated.

TRY IT YOURSELF

6-7. People: Make two new dictionaries representing different people, and store all three dictionaries in a list called people. Loop through your list of people. As you loop through the list, print everything you know about each person.

6-8. Pets: Make several dictionaries, where each dictionary represents a different pet. In each dictionary, include the kind of animal and the owner’s name. Store these dictionaries in a list called pets. Next, loop through your list and as you do, print everything you know about each pet.

6-9. Favorite Places: Make a dictionary called favorite_places. Think of three names to use as keys in the dictionary, and store one to three favorite places for each person. To make this exercise a bit more interesting, ask some friends to name a few of their favorite places. Loop through the dictionary, and print each person’s name and their favorite places.

6-11. Cities: Make a dictionary called cities. Use the names of three cities as keys in your dictionary. Create a dictionary of information about each city and include the country that the city is in, its approximate population, and one fact about that city. The keys for each city’s dictionary should be something like country, population, and fact. Print the name of each city and all of the information you have stored about it.

6-12. Extensions: We’re now working with examples that are complex enough that they can be extended in any number of ways. Use one of the example programs from this chapter, and extend it by adding new keys and values, changing the context of the program or improving the formatting of the output.

SUMMARY

In this tutorial, you learned how to define a dictionary and how to work with the information stored in a dictionary. You learned how to access and modify individual elements in a dictionary, and how to loop through all of the information in a dictionary. You learned to loop through a dictionary’s key-value pairs, its keys, and its values. You also learned how to nest multiple dictionaries in a list, nest lists in a dictionary, and nest a dictionary inside a dictionary.

More Pyhton tutorials on Dictionary

Written by

XR Developer responsible for end-to-end development of XR solutions spanning multiple domains, by using various XR and WebXR libraries.

Leave a Reply