How to Loop Over a Dictionary in Python: Keys, Values, and More

How to Loop Over a Dictionary in Python Featured Image

Welcome to yet another How to Python article. Today, we’ll be looking at looping over dictionaries which appears to be a hot topic—at least by an organic standpoint.

As it turns out, there are few ways to get it done. First, we could loop over the keys directly: for key in dictionary. Alternatively, we might only need to loop over the values: for value in dictionary.values(). That said, most folks probably need to be able to do both at the same time: for key, value in dictionary.items().

If you’re interested in learning more about these solutions, the remainder of this article will take some time to help you out. At the very least, I’d love it if you completed the challenge below.

Table of Contents

Problem Description

In the past, we talked about writing loops generally. Of course, when it comes to working with common data structures like lists and tuples in Python, looping over them is a breeze:

data = [1, 5, 4, 3]
for num in data:
  pass  # Do something!

However, once we start talking about more complicated data structures like dictionaries, iteration becomes a bit more complicated. For example, here’s a dictionary that we’ll be using throughout this article:

players = {
  "Crosby": 87,
  "Malkin": 71,
  "Letang": 58
}

If we want to loop over this, what order can we expect it to be in? And, does the concept of ordering even make sense? Likewise, what do the elements look like during iteration?

Before we dive in, I think it’s important to address a couple of these questions right out of the gate. First, dictionaries have a temporal ordering—at least since Python 3.7—which means that items are sorted by the order in which they were added.

That said, element question is a bit more complicated, so we’ll take the rest of this article to answer it.

Solutions

At this point, let’s go ahead and start talking about how to actually iterate over a dictionary. As it turns out, there are three main ways to do it, and it all depends on our needs. That said, we’ll start by looking at keys and values separately and finish up with a way to loop over both at the same time.

Iterating Over Dictionary Keys

If we were to use the same strategy on the dictionary as we did on the list above, we may find ourselves a little confused (as one individual does in this StackOverflow questionOpens in a new tab.):

players = {
  "Crosby": 87,
  "Malkin": 71,
  "Letang": 58
}

for player in players:
  print(player)

# Prints the following:
# Crosby
# Malkin
# Letang

As we can see, the player variable seems to store each key. To make use of this information, we’ll need to use these keys to access our values:

players = {
  "Crosby": 87,
  "Malkin": 71,
  "Letang": 58
}

for player in players:
  print(f'{player}\'s number is {players[player]}')

# Prints the following:
# Crosby's number is 87
# Malkin's number is 71
# Letang's number is 58

Notice how we used the player variable to access our players dictionary. On each pass, we picked up a new player and retrieved their number directly.

Iterating Over Dictionary Values

If for some reason, we don’t need keys, Python gives us the option to iterate over values instead:

players = {
  "Crosby": 87,
  "Malkin": 71,
  "Letang": 58
}

for number in players.values():
  print(number)

# Prints the following:
# 87
# 71
# 58

Here, we’ve used the values() method of dictionaries to retrieve an iterable dict_values object. That way, we’re able to loop over the values and work with them directly.

If for some reason, we needed to retrieve a key associated with a value, we can do that. In fact, I have an entire separate article on reverse dictionary lookups. That said, there’s probably an even better option coming up.

Iterating Over Dictionary Keys and Values

Up to this point, we’ve been iterating over the keys and values separately. As it turns out, there are ways to iterate over both at the same time:

players = {
  "Crosby": 87,
  "Malkin": 71,
  "Letang": 58
}

for player, number in players.items():
  print(f'{player}\'s number is {number}')

# Prints the following:
# Crosby's number is 87
# Malkin's number is 71
# Letang's number is 58
players = {
  "Crosby": 87,
  "Malkin": 71,
  "Letang": 58
}

for player, number in players.iteritems():
  print(f'{player}\'s number is {number}')

# Prints the following:
# Crosby's number is 87
# Malkin's number is 71
# Letang's number is 58

Assuming we’re using the latest version of Python, we can iterate over both keys and values at the same time using the items() method. Essentially, this method packages each key and value as a tuple which can be unpacked using the iterable unpacking syntax (aka destructuring for you JavaScript folks).

If you’re interested in learning more about iterable unpacking, I’ve included an example in a previous article in this series. Likewise, the feature also made an appearance on my list of the coolest programming language features.

At any rate, let’s go ahead and compare these three options in terms of performance.

Performance

To compare these solutions, we’ll need to come up with a consistent scenario. Here, we’ll assume that we’ll need both the key and the value. Obviously, this gives the advantage to the items() solution, so the rationale is that this is probably the most common scenario.

At any rate, we’ll be using the timeit library which runs code snippets as strings. If you’re interested in learning more about this testing process, check out my article on performance testing in Python. Otherwise, here are the strings:

setup = """
players = {
  "Crosby": 87,
  "Malkin": 71,
  "Letang": 58
}
"""

keys_solution = """
for player in players:
  player_info = f\"{player}'s number is {players[player]}\"
"""

values_solution = """
for number in players.values():
  player = next(player for player in players.keys() if players[player] == number)
  player_info = f\"{player}'s number is {players[player]}\"
"""

items_solution = """
for player, number in players.items():
  player_info = f\"{player}'s number is {number}\"
"""

Now that we have our strings, we can begin our testing:

>>> import timeit
>>> min(timeit.repeat(setup=setup, stmt=keys_solution))
0.6103567999998631
>>> min(timeit.repeat(setup=setup, stmt=values_solution))
2.5487096000001657
>>> min(timeit.repeat(setup=setup, stmt=items_solution))
0.6782263000000057

Clearly, this is a bit surprising because of the extra lookup required for the keys solution. I would have assumed that the items() solution would have won out. Naturally, I couldn’t help but test this problem with a larger data set, so I expanded our players dictionary:

setup = """
players = {
  "Crosby": 87,
  "Malkin": 71,
  "Letang": 58,
  "Guentzel": 59,
  "Aston-Reese": 46,
  "Blueger": 53,
  "Johnson": 3,
  "Jarry": 35,
  "Murray": 30,
  "Marino": 6,
  "Rust": 17,
  "Sheary": 43,
  "Zucker": 16
}
"""

Now that we have about 4 times the players, let’s check back in on our algorithms:

>>> min(timeit.repeat(setup=setup, stmt=keys_solution))
2.6091060999997353
>>> min(timeit.repeat(setup=setup, stmt=items_solution))
2.5544105999997555

This time around I didn’t bother testing the values solution because, well, it’s already quite slow. That said, it looks like the items solution is already starting to edge out the keys solution. I wonder what this test would look like with even more data. Feel free to give it a try and let me know!

For reference, I tested all this code on Python 3.7.3 in IDLE using Windows 10.

Challenge

Now that we know how to iterate over a dictionary, I’m wondering if we could take some of this knowledge to the next level. For instance, what if we had the following data structure:

health_data = (
  (
    "05-01-2020", # Date
    180.5,  # Weight
    8043  # Steps
  ) ...
)

In other words, we have some health data in the form of a tuple of tuples. Each inner tuple has three data items: date, weights, and steps. Is there some way we could effectively process each row of data using what we’ve learned today?

As always, I’ll share my answer on Twitter using #RenegadePythonOpens in a new tab.:

Are there other ways to do this? Why not share your own solution using the same hashtag? If I see it, I’ll give it a share!

A Little Recap

As always, here’s the list of solutions:

players = {
  "Crosby": 87,
  "Malkin": 71,
  "Letang": 58
}

# Loops over just the keys
for player in players:
  pass

# Loops over just the values
for number in players.values():
  pass

# Loops over both keys and values (Python 3)
for player, number in players.items():
  pass

# Loops over both keys and values (Python 2)
for player, number in players.iteritems():
  pass

Beyond that, we’re done here! If you’re interested in sticking around, here are few other dictionary articles:

Likewise, I’d love it if you checked out my article on ways to grow The Renegade Coder. In it, you’ll learn how to hop on my mailing list or join me on Patreon.

Otherwise, here are a few Python resources for the road on Amazon (ad):

With that said, thanks for hanging out! I appreciate your time.

How to Python (42 Articles)—Series Navigation

The How to Python tutorial series strays from the usual in-depth coding articles by exploring byte-sized problems in Python. In this series, students will dive into unique topics such as How to Invert a Dictionary, How to Sum Elements of Two Lists, and How to Check if a File Exists.

Each problem is explored from the naive approach to the ideal solution. Occasionally, there’ll be some just-for-fun solutions too. At the end of every article, you’ll find a recap full of code snippets for your own use. Don’t be afraid to take what you need!

If you’re not sure where to start, I recommend checking out our list of Python Code Snippets for Everyday Problems. In addition, you can find some of the snippets in a Jupyter notebook format on GitHubOpens in a new tab.,

If you have a problem of your own, feel free to ask. Someone else probably has the same problem. Enjoy How to Python!

Jeremy Grifski

Jeremy grew up in a small town where he enjoyed playing soccer and video games, practicing taekwondo, and trading Pokémon cards. Once out of the nest, he pursued a Bachelors in Computer Engineering with a minor in Game Design. After college, he spent about two years writing software for a major engineering company. Then, he earned a master's in Computer Science and Engineering. Today, he pursues a PhD in Engineering Education in order to ultimately land a teaching gig. In his spare time, Jeremy enjoys spending time with his wife and kid, playing Overwatch 2, Lethal Company, and Baldur's Gate 3, reading manga, watching Penguins hockey, and traveling the world.

Recent Code Posts