How to iterate over two dictionaries at once and get a result using values and keys from both

Learn how to iterate over two dictionaries at once and get a result using values and keys from both with practical examples, diagrams, and best practices. Covers python, loops development technique...

Iterating Over Two Dictionaries Simultaneously in Python

Hero image for How to iterate over two dictionaries at once and get a result using values and keys from both

Learn effective Python techniques to combine and process data from two dictionaries, leveraging keys and values from both in a single loop.

When working with Python, you often encounter scenarios where you need to process data from multiple sources. A common challenge is iterating over two dictionaries at once, especially when you need to access keys and values from both to produce a combined result. This article explores several robust methods to achieve this, catering to different requirements such as matching keys, handling missing keys, and combining values.

Understanding the Challenge

The core problem arises because Python's for loop typically iterates over a single iterable. When you have two dictionaries, dict1 and dict2, and you need to perform an operation that depends on corresponding elements (e.g., keys or values) from both, a direct for key, value in dict1, dict2: syntax doesn't exist. We need strategies to align the iteration based on common keys or a defined order.

flowchart TD
    A[Start]
    B{Need to combine dict1 and dict2?}
    C{Do dicts share common keys?}
    D[Use common keys for iteration]
    E[Iterate over one dict and lookup in other]
    F[Use `zip` with sorted keys]
    G[Handle missing keys with `get()` or `defaultdict`]
    H[Process combined data]
    I[End]

    A --> B
    B -->|Yes| C
    C -->|Yes| D
    C -->|No| E
    D --> G
    E --> G
    G --> H
    H --> I
    D --> F

Decision flow for iterating over two dictionaries.

Method 1: Iterating Over Common Keys

The most straightforward approach is when you're interested in keys that exist in both dictionaries. You can find the intersection of their key sets and then iterate through these common keys, accessing values from both dictionaries.

dict1 = {'a': 1, 'b': 2, 'c': 3}
dict2 = {'b': 20, 'c': 30, 'd': 40}

common_keys = dict1.keys() & dict2.keys()

print("Iterating over common keys:")
for key in common_keys:
    value1 = dict1[key]
    value2 = dict2[key]
    print(f"Key: {key}, Dict1 Value: {value1}, Dict2 Value: {value2}, Sum: {value1 + value2}")

Example of iterating over common keys in two dictionaries.

Method 2: Iterating Over All Keys from One Dictionary and Looking Up in the Other

Sometimes, you might want to iterate through all keys of one dictionary and, for each key, try to retrieve a corresponding value from the second dictionary. This method requires handling cases where a key might be present in the first dictionary but not in the second.

dict1 = {'a': 1, 'b': 2, 'c': 3}
dict2 = {'b': 20, 'd': 40}

print("\nIterating over dict1 keys and looking up in dict2:")
for key, value1 in dict1.items():
    value2 = dict2.get(key, None) # Use .get() to handle missing keys gracefully
    if value2 is not None:
        print(f"Key: {key}, Dict1 Value: {value1}, Dict2 Value: {value2}, Product: {value1 * value2}")
    else:
        print(f"Key: {key}, Dict1 Value: {value1}, Dict2 has no matching key.")

Using dict.get() to safely access values from the second dictionary.

Method 3: Combining Keys for Comprehensive Iteration

If you need to iterate over all unique keys present in either dictionary, you can combine their key sets. This approach ensures that no key is missed, and you can then use dict.get() for safe access to values from both dictionaries.

dict1 = {'a': 1, 'b': 2, 'c': 3}
dict2 = {'b': 20, 'd': 40, 'e': 50}

all_unique_keys = dict1.keys() | dict2.keys() # Union of keys

print("\nIterating over all unique keys:")
for key in sorted(all_unique_keys): # Sorting for consistent output
    value1 = dict1.get(key, 0) # Default to 0 if key not in dict1
    value2 = dict2.get(key, 0) # Default to 0 if key not in dict2
    print(f"Key: {key}, Dict1 Value: {value1}, Dict2 Value: {value2}, Combined: {value1 + value2}")

Iterating over the union of keys from both dictionaries.

Method 4: Using itertools.zip_longest for Paired Iteration (with caveats)

While zip is commonly used for parallel iteration, it stops at the shortest iterable. For dictionaries, if you want to pair items even when one dictionary has more keys, you'd typically need to sort keys and then use itertools.zip_longest. However, this method is generally less intuitive and more prone to errors if the dictionaries are not guaranteed to have the same keys or a predictable order. It's usually better to rely on key-based lookups as shown in previous methods.

from itertools import zip_longest

dict1 = {'a': 1, 'b': 2, 'c': 3}
dict2 = {'b': 20, 'd': 40}

# This approach is generally NOT recommended for dictionaries unless keys are guaranteed to align
# and you specifically want to pair based on sorted key order.

# Example (demonstrative, not best practice for general dict iteration):
keys1 = sorted(dict1.keys())
keys2 = sorted(dict2.keys())

print("\nUsing zip_longest with sorted keys (caution advised):")
for key1, key2 in zip_longest(keys1, keys2, fillvalue=None):
    value1 = dict1.get(key1) if key1 else None
    value2 = dict2.get(key2) if key2 else None
    print(f"Key1: {key1}, Value1: {value1} | Key2: {key2}, Value2: {value2}")

Demonstrative use of zip_longest with sorted dictionary keys. Note the complexity in handling None values.