How to Iterate Through a Dictionary in Python

How to Iterate Through a Dictionary in Python

by Leodanis Pozo Ramos May 27, 2019 intermediate python
Tweet Share Email

Dictionaries are one of the most important and useful data structures in Python. They can help you solve a wide variety of programming problems. This tutorial will take you on a deep dive into how to iterate through a dictionary in Python.

By the end of this tutorial, you’ll know:

  • What dictionaries are, as well as some of their main features and implementation details
  • How to iterate through a dictionary in Python by using the basic tools the language offers
  • What kind of real-world tasks you can perform by iterating through a dictionary in Python
  • How to use some more advanced techniques and strategies to iterate through a dictionary in Python

For more information on dictionaries, you can check out the following resources:

Ready? Let’s go!

A Few Words on Dictionaries

Dictionaries are a cornerstone of Python. The language itself is built around dictionaries. Modules, classes, objects, globals(), locals(): all of these are dictionaries. Dictionaries have been central to Python from its very beginning.

Python’s official documentation defines a dictionary as follows:

An associative array, where arbitrary keys are mapped to values. The keys can be any object with __hash__() and __eq__() methods. (Source)

There are a couple points to keep in mind:

  1. Dictionaries map keys to values and store them in an array or collection.
  2. The keys must be of a hashable type, which means that they must have a hash value that never changes during the key’s lifetime.

Dictionaries are frequently used for solving all kinds of programming problems, so they are a fundamental piece of your tool kit as a Python developer.

Unlike sequences, which are iterables that support element access using integer indices, dictionaries are indexed by keys.

The keys in a dictionary are much like a set, which is a collection of hashable and unique objects. Because the objects need to be hashable, mutable objects can’t be used as dictionary keys.

On the other hand, values can be of any Python type, whether they are hashable or not. There are literally no restrictions for values.

In Python 3.6 and beyond, the keys and values of a dictionary are iterated over in the same order in which they were created. However, this behavior may vary across different Python versions, and it depends on the dictionary’s history of insertions and deletions.

In Python 2.7, dictionaries are unordered structures. The order of the dictionaries’ items is scrambled. This means that the order of the items is deterministic and repeatable. Let’s see an example:

>>>
>>> # Python 2.7
>>> a_dict = {'color': 'blue', 'fruit': 'apple', 'pet': 'dog'}
>>> a_dict
{'color': 'blue', 'pet': 'dog', 'fruit': 'apple'}
>>> a_dict
{'color': 'blue', 'pet': 'dog', 'fruit': 'apple'}

If you leave the interpreter and open a new interactive session later, you’ll get the same item order:

>>>
>>> # Python 2.7. New interactive session
>>> a_dict = {'color': 'blue', 'fruit': 'apple', 'pet': 'dog'}
>>> a_dict
{'color': 'blue', 'pet': 'dog', 'fruit': 'apple'}
>>> a_dict
{'color': 'blue', 'pet': 'dog', 'fruit': 'apple'}

A closer look at these two outputs shows you that the resulting order is exactly the same in both cases. That’s why you can say that the ordering is deterministic.

In Python 3.5, dictionaries are still unordered, but this time, randomized data structures. This means that every time you re-run the dictionary, you’ll get a different items order. Let’s take a look:

>>>
>>> # Python 3.5
>>> a_dict = {'color': 'blue', 'fruit': 'apple', 'pet': 'dog'}
>>> a_dict
{'color': 'blue', 'pet': 'dog', 'fruit': 'apple'}
>>> a_dict
{'color': 'blue', 'pet': 'dog', 'fruit': 'apple'}

If you enter a new interactive session, then you’ll get the following:

>>>
>>> # Python 3.5. New interactive session
>>> a_dict = {'color': 'blue', 'fruit': 'apple', 'pet': 'dog'}
>>> a_dict
{'fruit': 'apple', 'pet': 'dog', 'color': 'blue'}
>>> a_dict
{'fruit': 'apple', 'pet': 'dog', 'color': 'blue'}

This time, you can see that the order of the items is different in both outputs. That’s why you can say they are randomized data structures.

In Python 3.6 and beyond, dictionaries are ordered data structures, which means that they keep their elements in the same order in which they were introduced, as you can see here:

>>>
>>> # Python 3.6 and beyond
>>> a_dict = {'color': 'blue', 'fruit': 'apple', 'pet': 'dog'}
>>> a_dict
{'color': 'blue', 'fruit': 'apple', 'pet': 'dog'}
>>> a_dict
{'color': 'blue', 'fruit': 'apple', 'pet': 'dog'}

This is a relatively new feature of Python’s dictionaries, and it’s a very useful one. But if you’re writing code that is supposed to be run in different Python versions, then you must not rely on this feature, because it can generate buggy behaviors.

Another important feature of dictionaries is that they are mutable data structures, which means that you can add, delete, and update their items. It’s worth noting that this also means that they can’t be used as keys to other dictionaries, as they are not hashable objects.

How to Iterate Through a Dictionary in Python: The Basics

Dictionaries are an useful and widely used data structure in Python. As a Python coder, you’ll often be in situations where you’ll need to iterate through a dictionary in Python, while you perform some actions on its key-value pairs.

When it comes to iterating through a dictionary in Python, the language provides you with some great tools that we’ll cover in this article.

Iterating Through Keys Directly

Python’s dictionaries are mapping objects. This means that they inherit some special methods, which Python uses internally to perform some operations. These methods are named using the naming convention of adding a double underscore at the beginning of and at the end of the method’s name.

To visualize the methods and attributes of any Python object, you can use dir(), which is a built-in function that serves that purpose. If you run dir() with an empty dictionary as an argument, then you’ll be able to see all the methods and attributes that dictionaries implement:

>>>
>>> dir({})
['__class__', '__contains__', '__delattr__', ... , '__iter__', ...]

If you take a closer look at the previous output, you’ll see '__iter__'. This is a method that is called when an iterator is required for a container, and it should return a new iterator object that can iterate through all the objects in the container.

For mappings (like dictionaries), .__iter__() should iterate over the keys. This means that if you put a dictionary directly into a for loop, Python will automatically call .__iter__() on that dictionary, and you’ll get an iterator over its keys:

>>>
>>> a_dict = {'color': 'blue', 'fruit': 'apple', 'pet': 'dog'}
>>> for key in a_dict:
...     print(key)
...
color
fruit
pet

Python is smart enough to know that a_dict is a dictionary and that it implements .__iter__(). In this example, Python called .__iter__() automatically, and this allowed you to iterate over the keys of a_dict.

This is the simplest way to iterate through a dictionary in Python. Just put it directly into a for loop, and you’re done!

If you use this approach along with a small trick, then you can process the keys and values of any dictionary. The trick consists of using the indexing operator [] with the dictionary and its keys to get access to the values:

>>>
>>> for key in a_dict:
...     print(key, '->', a_dict[key])
...
color -> blue
fruit -> apple
pet -> dog

The preceding code allowed you to get access to the keys (key) and the values (a_dict[key]) of a_dict at the same time. This way, you can do any operation with both the keys and the values.

Iterating Through .items()

When you’re working with dictionaries, it’s likely that you’ll want to work with both the keys and the values. One of the most useful ways to iterate through a dictionary in Python is by using .items(), which is a method that returns a new view of the dictionary’s items:

>>>
>>> a_dict = {'color': 'blue', 'fruit': 'apple', 'pet': 'dog'}
>>> d_items = a_dict.items()
>>> d_items  # Here d_items is a view of items
dict_items([('color', 'blue'), ('fruit', 'apple'), ('pet', 'dog')])

Dictionary views like d_items provide a dynamic view on the dictionary’s entries, which means that when the dictionary changes, the views reflect these changes.

Views can be iterated over to yield their respective data, so you can iterate through a dictionary in Python by using the view object returned by .items():

>>>
>>> for item in a_dict.items():
...     print(item)
...
('color', 'blue')
('fruit', 'apple')
('pet', 'dog')

The view object returned by .items() yields the key-value pairs one at a time and allows you to iterate through a dictionary in Python, but in such a way that you get access to the keys and values at the same time.

If you take a closer look at the individual items yielded by .items(), you’ll notice that they’re really tuple objects. Let’s take a look:

>>>
>>> for item in a_dict.items():
...     print(item)
...     print(type(item))
...
('color', 'blue')
<class 'tuple'>
('fruit', 'apple')
<class 'tuple'>
('pet', 'dog')
<class 'tuple'>

Once you know this, you can use tuple unpacking to iterate through the keys and values of the dictionary you are working with. To achieve this, you just need to unpack the elements of every item into two different variables representing the key and the value:

>>>
>>> for key, value in a_dict.items():
...     print(key, '->', value)
...
color -> blue
fruit -> apple
pet -> dog

Here, the variables key and value in the header of your for loop do the unpacking. Every time the loop runs, key will store the key, and value will store the value of the item that is been processed. This way, you’ll have more control over the items of the dictionary, and you’ll be able to process the keys and values separately and in a way that is more readable and Pythonic.

Iterating Through .keys()

If you just need to work with the keys of a dictionary, then you can use .keys(), which is a method that returns a new view object containing the dictionary’s keys:

>>>
>>> a_dict = {'color': 'blue', 'fruit': 'apple', 'pet': 'dog'}
>>> keys = a_dict.keys()
>>> keys
dict_keys(['color', 'fruit', 'pet'])

The object returned by .keys() here provided a dynamic view on the keys of a_dict. This view can be used to iterate through the keys of a_dict.

To iterate through a dictionary in Python by using .keys(), you just need to call .keys() in the header of a for loop:

>>>
>>> for key in a_dict.keys():
...     print(key)
...
color
fruit
pet

When you call .keys() on a_dict, you get a view of keys. Python knows that view objects are iterables, so it starts looping, and you can process the keys of a_dict.

On the other hand, using the same trick you’ve seen before (indexing operator []), you can get access to the values of the dictionary:

>>>
>>> for key in a_dict.keys():
...     print(key, '->', a_dict[key])
...
color -> blue
fruit -> apple
pet -> dog

This way you’ve gotten access to the keys (key) and values (a_dict[key]) of a_dict at the same time, and you’ll be able to perform any action on them.

Iterating Through .values()

It’s also common to only use the values to iterate through a dictionary in Python. One way to do that is to use .values(), which returns a view with the values of the dictionary:

>>>
>>> a_dict = {'color': 'blue', 'fruit': 'apple', 'pet': 'dog'}
>>> values = a_dict.values()
>>> values
dict_values(['blue', 'apple', 'dog'])

In the previous code, values holds a reference to a view object containing the values of a_dict.

As any view object, the object returned by .values() can also be iterated over. In this case, .values() yields the values of a_dict:

>>>
>>> for value in a_dict.values():
...     print(value)
...
blue
apple
dog

Using .values(), you’ll be getting access to only the values of a_dict, without dealing with the keys.

It’s worth noting that they also support membership tests (in), which is an important feature if you’re trying to know if a specific element is in a dictionary or not:

>>>
>>> a_dict = {'color': 'blue', 'fruit': 'apple', 'pet': 'dog'}
>>> 'pet' in a_dict.keys()
True
>>> 'apple' in a_dict.values()
True
>>> 'onion' in a_dict.values()
False

The membership test using in returns True if the key (or value or item) is present in the dictionary you’re testing, and returns False otherwise. The membership test allows you to not iterate through a dictionary in Python if you just want to know if certain key (or value or item) is present in a dictionary or not.

Modifying Values and Keys

It can be pretty common to need to modify the values and keys when you’re iterating through a dictionary in Python. There are some points you’ll need to take into account to accomplish this task.

The values, for example, can be modified whenever you need, but you’ll need to use the original dictionary and the key that maps the value you want to modify:

>>>
>>> prices = {'apple': 0.40, 'orange': 0.35, 'banana': 0.25}
>>> for k, v in prices.items():
...     prices[k] = round(v * 0.9, 2)  # Apply a 10% discount
...
>>> prices
{'apple': 0.36, 'orange': 0.32, 'banana': 0.23}

In the previous code example, to modify the values of prices and apply a 10% discount, you used the expression prices[k] = round(v * 0.9, 2).

So why do you have to use the original dictionary if you have access to its key (k) and its values (v)? Should you be able to modify them directly?

The real problem is that k and v changes aren’t reflected in the original dictionary. That is, if you modify any of them (k or v) directly inside the loop, then what really happens is that you’ll lose the reference to the relevant dictionary component without changing anything in the dictionary.

On the other hand, the keys can be added or removed from a dictionary by converting the view returned by .keys() into a list object:

>>>
>>> prices = {'apple': 0.40, 'orange': 0.35, 'banana': 0.25}
>>> for key in list(prices.keys()):  # Use a list instead of a view
...     if key == 'orange':
...         del prices[key]  # Delete a key from prices
...
>>> prices
{'apple': 0.4, 'banana': 0.25}

This approach may have some performance implications, mainly related to memory consumption. For example, instead of a view object that yields elements on demand, you’ll have an entire new list in your system’s memory. However, this could be a safe way to modify the keys while you iterate through a dictionary in Python.

Finally, if you try to remove a key from prices by using .keys() directly, then Python will raise a RuntimeError telling you that the dictionary’s size has changed during iteration:

>>>
>>> # Python 3. dict.keys() returns a view object, not a list
>>> prices = {'apple': 0.40, 'orange': 0.35, 'banana': 0.25}
>>> for key in prices.keys():
...     if key == 'orange':
...         del prices[key]
...
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    for key in prices.keys():
RuntimeError: dictionary changed size during iteration

This is because .keys() returns a dictionary-view object, which yields keys on demand one at a time, and if you delete an item (del prices[key]), then Python raises a RuntimeError, because you’ve modified the dictionary during iteration.

Real-World Examples

So far, you’ve seen the more basic ways of iterating through a dictionary in Python. Now it’s time to see how you can perform some actions with the items of a dictionary during iteration. Let’s look at some real-world examples.

Turning Keys Into Values and Vice Versa

Suppose you have a dictionary and for some reason need to turn keys into values and vice versa. In this situation, you can use a for loop to iterate through the dictionary and build the new dictionary by using the keys as values and vice versa:

>>>
>>> a_dict = {'one': 1, 'two': 2, 'thee': 3, 'four': 4}
>>> new_dict = {}
>>> for key, value in a_dict.items():
...     new_dict[value] = key
...
>>> new_dict
{1: 'one', 2: 'two', 3: 'thee', 4: 'four'}

The expression new_dict[value] = key did all the work for you by turning the keys into values and using the values as keys. For this code to work, the data stored in the original values must be of a hashable data type.

Filtering Items

Sometimes you’ll be in situations where you have a dictionary and you want to create a new one to store only the data that satisfies a given condition. You can do this with an if statement inside a for loop as follows:

>>>
>>> a_dict = {'one': 1, 'two': 2, 'thee': 3, 'four': 4}
>>> new_dict = {}  # Create a new empty dictionary
>>> for key, value in a_dict.items():
...     # If value satisfies the condition, then store it in new_dict
...     if value <= 2:
...         new_dict[key] = value
...
>>> new_dict
{'one': 1, 'two': 2}

In this example, you’ve filtered out the items with a value greater than 2. Now new_dict only contains the items that satisfy the condition value <= 2. This is one possible solution for this kind of problem. Later on, you’ll see a more Pythonic and readable way to get the same result.

Doing Some Calculations

It’s also common to need to do some calculations while you iterate through a dictionary in Python. Suppose you’ve stored the data for your company’s sales in a dictionary, and now you want to know the total income of the year.

To solve this problem you could define a variable with an initial value of zero. Then, you can accumulate every value of your dictionary in that variable:

>>>
>>> incomes = {'apple': 5600.00, 'orange': 3500.00, 'banana': 5000.00}
>>> total_income = 0.00
>>> for value in incomes.values():
...     total_income += value  # Accumulate the values in total_income
...
>>> total_income
14100.0

Here, you’ve iterated through incomes and sequentially accumulated its values in total_income as you wanted to do. The expression total_income += value does the magic, and at the end of the loop, you’ll get the total income of the year. Note that total_income += value is equivalent to total_income = total_income + value.

Using Comprehensions

A dictionary comprehension is a compact way to process all or part of the elements in a collection and return a dictionary as a results. In contrast to list comprehensions, they need two expressions separated with a colon followed by for and if (optional) clauses. When a dictionary comprehension is run, the resulting key-value pairs are inserted into a new dictionary in the same order in which they were produced.

Suppose, for example, that you have two lists of data, and you need to create a new dictionary from them. In this case, you can use Python’s zip(*iterables) to loop over the elements of both lists in pairs:

>>>
>>> objects = ['blue', 'apple', 'dog']
>>> categories = ['color', 'fruit', 'pet']
>>> a_dict = {key: value for key, value in zip(categories, objects)}
>>> a_dict
{'color': 'blue', 'fruit': 'apple', 'pet': 'dog'}

Here, zip() receives two iterables (categories and objects) as arguments and makes an iterator that aggregates elements from each iterable. The tuple objects generated by zip() are then unpacked into key and value, which are finally used to create the new dictionary.

Dictionary comprehensions open up a wide spectrum of new possibilities and provide you with a great tool to iterate through a dictionary in Python.

Turning Keys Into Values and Vice Versa: Revisited

If you take another look at the problem of turning keys into values and vice versa, you’ll see that you could write a more Pythonic and efficient solution by using a dictionary comprehension:

>>>
>>> a_dict = {'one': 1, 'two': 2, 'thee': 3, 'four': 4}
>>> new_dict = {value: key for key, value in a_dict.items()}
>>> new_dict
{1: 'one', 2: 'two', 3: 'thee', 4: 'four'}

With this dictionary comprehension, you’ve created a totally new dictionary where the keys have taken the place of the values and vice versa. This new approach gave you the ability to write more readable, succinct, efficient, and Pythonic code.

The condition for this code to work is the same one you saw before: the values must be hashable objects. Otherwise, you won’t be able to use them as keys for a_dict.

Filtering Items: Revisited

To filter the items in a dictionary with a comprehension, you just need to add an if clause that defines the condition you want to meet. In the previous example where you filtered a dictionary, that condition was if v <= 2. With this if clause added to the end of the dictionary comprehension, you’ll filter out the items whose values are greater than 2. Let’s take a look:

>>>
>>> a_dict = {'one': 1, 'two': 2, 'thee': 3, 'four': 4}
>>> new_dict = {k: v for k, v in a_dict.items() if v <= 2}
>>> new_dict
{'one': 1, 'two': 2}

Now new_dict contains only the items that satisfy your condition. Compared to the previous solutions, this one is more Pythonic and efficient.

Doing Some Calculations: Revisited

Remember the example with the company’s sales? If you use a list comprehension to iterate through the dictionary’s values, then you’ll get code that is more compact, fast, and Pythonic:

>>>
>>> incomes = {'apple': 5600.00, 'orange': 3500.00, 'banana': 5000.00}
>>> total_income = sum([value for value in incomes.values()])
>>> total_income
14100.0

The list comprehension created a list object containing the values of incomes, and then you summed up all of them by using sum() and stored the result in total_income.

If you’re working with a really large dictionary, and memory usage is a problem for you, then you can use a generator expression instead of a list comprehension. A generator expression is an expression that returns an iterator. It looks like a list comprehension, but instead of brackets you need to use parentheses to define it:

>>>
>>> total_income = sum(value for value in incomes.values())
>>> total_income
14100.0

If you change the square brackets for a pair of parentheses (the parentheses of sum() here), you’ll be turning the list comprehension into a generator expression, and your code will be memory efficient, because generator expressions yield elements on demand. Instead of creating and storing the whole list in memory, you’ll only have to store one element at a time.

Finally, there is a simpler way to solve this problem by just using incomes.values() directly as an argument to sum():

>>>
>>> total_income = sum(incomes.values())
>>> total_income
14100.0

sum() receives an iterable as an argument and returns the total sum of its elements. Here, incomes.values() plays the role of the iterable passed to sum(). The result is the total income you were looking for.

Removing Specific Items

Now, suppose you have a dictionary and need to create a new one with selected keys removed. Remember how key-view objects are like sets? Well, these similarities go beyond just being collections of hashable and unique objects. Key-view objects also support common set operations. Let’s see how you can take advantage of this to remove specific items in a dictionary:

>>>
>>> incomes = {'apple': 5600.00, 'orange': 3500.00, 'banana': 5000.00}
>>> non_citric = {k: incomes[k] for k in incomes.keys() - {'orange'}}
>>> non_citric
{'apple': 5600.0, 'banana': 5000.0}

This code works because key-view objects support set operations like unions, intersections, and differences. When you wrote incomes.keys() - {'orange'} inside the dictionary comprehension, you were really doing a set difference operation. If you need to perform any set operations with the keys of a dictionary, then you can just use the key-view object directly without first converting it into a set. This is a little-known feature of key-view objects that can be useful in some situations.

Sorting a Dictionary

It’s often necessary to sort the elements of a collection. Since Python 3.6, dictionaries are ordered data structures, so if you use Python 3.6 (and beyond), you’ll be able to sort the items of any dictionary by using sorted() and with the help of a dictionary comprehension:

>>>
>>> # Python 3.6, and beyond
>>> incomes = {'apple': 5600.00, 'orange': 3500.00, 'banana': 5000.00}
>>> sorted_income = {k: incomes[k] for k in sorted(incomes)}
>>> sorted_income
{'apple': 5600.0, 'banana': 5000.0, 'orange': 3500.0}

This code allows you to create a new dictionary with its keys in sorted order. This is possible because sorted(incomes) returns a list of sorted keys that you can use to generate the new dictionary sorted_dict.

Iterating in Sorted Order

Sometimes you may need to iterate through a dictionary in Python but want to do it in sorted order. This can be achieved by using sorted(). When you call sorted(iterable), you get a list with the elements of iterable in sorted order.

Let’s see how you can use sorted() to iterate through a dictionary in Python when you need to do it in sorted order.

Sorted by Keys

If you need to iterate through a dictionary in Python and want it to be sorted by keys, then you can use your dictionary as an argument to sorted(). This will return a list containing the keys in sorted order, and you’ll be able to iterate through them:

>>>
>>> incomes = {'apple': 5600.00, 'orange': 3500.00, 'banana': 5000.00}
>>> for key in sorted(incomes):
...     print(key, '->', incomes[key])
...
apple -> 5600.0
banana -> 5000.0
orange -> 3500.0

In this example, you sorted the dictionary (alphabetically) by keys using sorted(incomes) in the header of the for loop. Notice that you can also use sorted(incomes.keys()) to get the same result. In both cases, you’ll get a list containing the keys of your dictionary in sorted order.

Sorted by Values

You could also need to iterate through a dictionary in Python with its items sorted by values. You can use sorted() too, but with a second argument called key.

The key keyword argument specifies a function of one argument that is used to extract a comparison key from each element you’re processing.

To sort the items of a dictionary by values, you can write a function that returns the value of each item and use this function as the key argument to sorted():

>>>
>>> incomes = {'apple': 5600.00, 'orange': 3500.00, 'banana': 5000.00}
>>> def by_value(item):
...     return item[1]
...
>>> for k, v in sorted(incomes.items(), key=by_value):
...     print(k, '->', v)
...
('orange', '->', 3500.0)
('banana', '->', 5000.0)
('apple', '->', 5600.0)

In this example, you defined by_value() and used it to sort the items of incomes by value. Then you iterated through the dictionary in sorted order by using sorted(). The key function (by_value()) tells sorted() to sort incomes.items() by the second element of each item, that is, by the value (item[1]).

You may also just want to iterate through the values of a dictionary in sorted order, without worrying about the keys. In that case, you can use .values() as follows:

>>>
>>> for value in sorted(incomes.values()):
...     print(value)
...
3500.0
5000.0
5600.0

sorted(incomes.values()) returned the values of the dictionary in sorted order as you desired. The keys won’t be accessible if you use incomes.values(), but sometimes you don’t really need the keys, just the values, and this is a fast way to get access to them.

Reversed

If you need to sort your dictionaries in reverse order, you can add reverse=True as an argument to sorted(). The keyword argument reverse should take a boolean value. If it’s set to True, then the elements are sorted in reverse order:

>>>
>>> incomes = {'apple': 5600.00, 'orange': 3500.00, 'banana': 5000.00}
>>> for key in sorted(incomes, reverse=True):
...     print(key, '->', incomes[key])
...
orange -> 3500.0
banana -> 5000.0
apple -> 5600.0

Here, you iterated over the keys of incomes in reverse order by using sorted(incomes, reverse=True) in the header of the for loop.

Finally, it’s important to note that sorted() doesn’t really modify the order of the underlying dictionary. What really happen is that sorted() creates an independent list with its element in sorted order, so incomes remains the same:

>>>
>>> incomes
{'apple': 5600.0, 'orange': 3500.0, 'banana': 5000.0}

This code shows you that incomes didn’t change. sorted() didn’t modify incomes. It just created a new sorted list from the keys of incomes.

Iterating Destructively With .popitem()

Sometimes you need to iterate through a dictionary in Python and delete its items sequentially. To accomplish this task, you can use .popitem(), which will remove and return an arbitrary key-value pair from a dictionary. On the other hand, when you call .popitem() on an empty dictionary, it raises a KeyError.

If you really need to destructively iterate through a dictionary in Python, then .popitem() can be useful. Here’s an example:

 1 # File: dict_popitem.py
 2 
 3 a_dict = {'color': 'blue', 'fruit': 'apple', 'pet': 'dog'}
 4 
 5 while True:
 6     try:
 7         print(f'Dictionary length: {len(a_dict)}')
 8         item = a_dict.popitem()
 9         # Do something with item here...
10         print(f'{item} removed')
11     except KeyError:
12         print('The dictionary has no item now...')
13         break

Here, you used a while loop instead of a for loop. The reason for this is that it’s never safe to iterate through a dictionary in Python if you pretend to modify it this way, that is, if you’re deleting or adding items to it.

Inside the while loop, you defined a try...except block to catch the KeyError raised by .popitems() when a_dict turns empty. In the try...except block, you process the dictionary, removing an item in each iteration. The variable item keeps a reference to the successive items and allows you to do some actions with them.

If you run this script from your command-line, then you’ll get the following results:

$ python3 dict_popitem.py
Dictionary length: 3
('pet', 'dog') removed
Dictionary length: 2
('fruit', 'apple') removed
Dictionary length: 1
('color', 'blue') removed
Dictionary length: 0
The dictionary has no item now...

Here .popitem() sequentially removed the items of a_dict. The loop broke when the dictionary became empty, and .popitem() raised a KeyError exception.

Using Some of Python’s Built-In Functions

Python provides some built-in functions that could be useful when you’re working with collections, like dictionaries. These functions are a sort of iteration tool that provides you with another way of iterating through a dictionary in Python. Let’s see some of them.

map()

Python’s map() is defined as map(function, iterable, ...) and returns an iterator that applies function to every item of iterable, yielding the results on demand. So, map() could be viewed as an iteration tool that you can use to iterate through a dictionary in Python.

Suppose you have a dictionary containing the prices of a bunch of products, and you need to apply a discount to them. In this case, you can define a function that manages the discount and then uses it as the first argument to map(). The second argument can be prices.items():

>>>
>>> prices = {'apple': 0.40, 'orange': 0.35, 'banana': 0.25}
>>> def discount(current_price):
...     return (current_price[0], round(current_price[1] * 0.95, 2))
...
>>> new_prices = dict(map(discount, prices.items()))
>>> new_prices
{'apple': 0.38, 'orange': 0.33, 'banana': 0.24}

Here, map() iterated through the items of the dictionary (prices.items()) to apply a 5% discount to each fruit by using discount(). In this case, you need to use dict() to generate the new_prices dictionary from the iterator returned by map().

Note that discount() returns a tuple of the form (key, value), where current_price[0] represents the key and round(current_price[1] * 0.95, 2) represents the new value.

filter()

filter() is another built-in function that you can use to iterate through a dictionary in Python and filter out some of its items. This function is defined as filter(function, iterable) and returns an iterator from those elements of iterable for which function returns True.

Suppose you want to know the products with a price lower than 0.40. You need to define a function to determine if the price satisfies that condition and pass it as first argument to filter(). The second argument can be prices.keys():

>>>
>>> prices = {'apple': 0.40, 'orange': 0.35, 'banana': 0.25}
>>> def has_low_price(price):
...     return prices[price] < 0.4
...
>>> low_price = list(filter(has_low_price, prices.keys()))
>>> low_price
['orange', 'banana']

Here, you iterated through the keys of prices with filter(). Then filter() applies has_low_price() to every key of prices. Finally, you need to use list() to generate the list of products with a low price, because filter() returns an iterator, and you really need a list object.

Using collections.ChainMap

collections is a useful module from the Python Standard Library that provides specialized container data types. One of these data types is ChainMap, which is a dictionary-like class for creating a single view of multiple mappings (like dictionaries). With ChainMap, you can group multiple dictionaries together to create a single, updateable view.

Now, suppose you have two (or more) dictionaries, and you need to iterate through them together as one. To achieve this, you can create a ChainMap object and initialize it with your dictionaries:

>>>
>>> from collections import ChainMap
>>> fruit_prices = {'apple': 0.40, 'orange': 0.35}
>>> vegetable_prices = {'pepper': 0.20, 'onion': 0.55}
>>> chained_dict = ChainMap(fruit_prices, vegetable_prices)
>>> chained_dict  # A ChainMap object
ChainMap({'apple': 0.4, 'orange': 0.35}, {'pepper': 0.2, 'onion': 0.55})
>>> for key in chained_dict:
...     print(key, '->', chained_dict[key])
...
pepper -> 0.2
orange -> 0.35
onion -> 0.55
apple -> 0.4

After importing ChainMap from collections, you need to create a ChainMap object with the dictionaries you want to chain, and then you can freely iterate through the resulting object as you would do with a regular dictionary.

ChainMap objects also implement .keys(), values(), and .items() as a standard dictionary does, so you can use these methods to iterate through the dictionary-like object generated by ChainMap, just like you would do with a regular dictionary:

>>>
>>> for key, value in chained_dict.items():
...     print(key, '->', value)
...
apple -> 0.4
pepper -> 0.2
orange -> 0.35
onion -> 0.55

In this case, you’ve called .items() on a ChainMap object. The ChainMap object behaved as if it were a regular dictionary, and .items() returned a dictionary view object that can be iterated over as usual.

Using itertools

Python’s itertools is a module that provides some useful tools to perform iteration tasks. Let’s see how you can use some of them to iterate through a dictionary in Python.

Cyclic Iteration With cycle()

Suppose you want to iterate through a dictionary in Python, but you need to iterate through it repeatedly in a single loop. To get this task done, you can use itertools.cycle(iterable), which makes an iterator returning elements from iterable and saving a copy of each. When iterable is exhausted, cycle() returns elements from the saved copy. This is performed in cyclic fashion, so it’s up to you to stop the cycle.

In the following example, you’ll be iterating through the items of a dictionary three consecutive times:

>>>
>>> from itertools import cycle
>>> prices = {'apple': 0.40, 'orange': 0.35, 'banana': 0.25}
>>> times = 3  # Define how many times you need to iterate through prices
>>> total_items = times * len(prices)
>>> for item in cycle(prices.items()):
...     if not total_items:
...         break
...     total_items -= 1
...     print(item)
...
('apple', 0.4)
('orange', 0.35)
('banana', 0.25)
('apple', 0.4)
('orange', 0.35)
('banana', 0.25)
('apple', 0.4)
('orange', 0.35)
('banana', 0.25)

The preceding code allowed you to iterate through prices a given number of times (3 in this case). This cycle could be as long as you need, but you are responsible for stopping it. The if condition breaks the cycle when total_items counts down to zero.

Chained Iteration With chain()

itertools also provides chain(*iterables), which gets some iterables as arguments and makes an iterator that yields elements from the first iterable until it’s exhausted, then iterates over the next iterable and so on, until all of them are exhausted.

This allows you to iterate through multiple dictionaries in a chain, like to what you did with collections.ChainMap:

>>>
>>> from itertools import chain
>>> fruit_prices = {'apple': 0.40, 'orange': 0.35, 'banana': 0.25}
>>> vegetable_prices = {'pepper': 0.20, 'onion': 0.55, 'tomato': 0.42}
>>> for item in chain(fruit_prices.items(), vegetable_prices.items()):
...     print(item)
...
('apple', 0.4)
('orange', 0.35)
('banana', 0.25)
('pepper', 0.2)
('onion', 0.55)
('tomato', 0.42)

In the above code, chain() returned an iterable that combined the items from fruit_prices and vegetable_prices.

It’s also possible to use .keys() or .values(), depending on your needs, with the condition of being homogeneous: if you use .keys() for an argument to chain(), then you need to use .keys() for the rest of them.

Using the Dictionary Unpacking Operator (**)

Python 3.5 brings a new and interesting feature. PEP 448 - Additional Unpacking Generalizations can make your life easier when it comes to iterating through multiple dictionaries in Python. Let’s see how this works with a short example.

Suppose you have two (or more) dictionaries, and you need to iterate through them together, without using collections.ChainMap or itertools.chain(), as you’ve seen in the previous sections. In this case, you can use the dictionary unpacking operator (**) to merge the two dictionaries into a new one and then iterate through it:

>>>
>>> fruit_prices = {'apple': 0.40, 'orange': 0.35}
>>> vegetable_prices = {'pepper': 0.20, 'onion': 0.55}
>>> # How to use the unpacking operator **
>>> {**vegetable_prices, **fruit_prices}
{'pepper': 0.2, 'onion': 0.55, 'apple': 0.4, 'orange': 0.35}
>>> # You can use this feature to iterate through multiple dictionaries
>>> for k, v in {**vegetable_prices, **fruit_prices}.items():
...     print(k, '->', v)
...
pepper -> 0.2
onion -> 0.55
apple -> 0.4
orange -> 0.35

The dictionary unpacking operator (**) is really an awesome feature in Python. It allows you to merge multiple dictionaries into a new one, as you did in the example with vegetable_prices and fruit_prices. Once you’ve merged the dictionaries with the unpacking operator, you can iterate through the new dictionary as usual.

It’s important to note that if the dictionaries you’re trying to merge have repeated or common keys, then the values of the right-most dictionary will prevail:

>>>
>>> vegetable_prices = {'pepper': 0.20, 'onion': 0.55}
>>> fruit_prices = {'apple': 0.40, 'orange': 0.35, 'pepper': .25}
>>> {**vegetable_prices, **fruit_prices}
{'pepper': 0.25, 'onion': 0.55, 'apple': 0.4, 'orange': 0.35}

The pepper key is present in both dictionaries. After you merge them, the fruit_prices value for pepper (0.25) prevailed, because fruit_prices is the right-most dictionary.

Conclusion

You now know the basics of how to iterate through a dictionary in Python, as well as some more advanced techniques and strategies!

You’ve learned:

  • What dictionaries are, as well as some of their main features and implementation details
  • What the basic ways to iterate through a dictionary in Python are
  • What kind of tasks you can accomplish by iterating through a dictionary in Python
  • How to use some more elaborated techniques and strategies to iterate through a dictionary in Python

You have the tools and knowledge you’ll need to get the most out of dictionaries in Python. This will help you be more efficient and effective in your use of dictionary iteration in the future.

🐍 Python Tricks πŸ’Œ

Get a short & sweet Python Trick delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team.

Python Tricks Dictionary Merge

About Leodanis Pozo Ramos

Leodanis Pozo Ramos

Leodanis is an industrial engineer who loves Python and software development. He is a self-taught Python programmer with 5+ years of experience building desktop applications.

Β» More about Leodanis

Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are:

What Do You Think?

Real Python Comment Policy: The most useful comments are those written with the goal of learning from or helping out other readersβ€”after reading the whole article and all the earlier comments. Complaints and insults generally won’t make the cut here.

Keep Learning

Related Tutorial Categories: intermediate python