How reverse / invert a dictionary mapping in Python ?

To reverse or invert a dictionary in Python, you need to swap keys and values. This process can vary depending on whether the original dictionary’s values are unique or may contain duplicates. Below are the methods to handle both scenarios, along with examples:

1. Inverting a Dictionary with Unique Values

If all values in the dictionary are unique and hashable (e.g., strings, numbers), use a dictionary comprehension to swap keys and values.

Example:

original_dict = {
    "apple": "fruit",
    "carrot": "vegetable",
    "chicken": "meat"
}

# Invert the dictionary
inverted_dict = {v: k for k, v in original_dict.items()}

print(inverted_dict)

Output:

{'fruit': 'apple', 'vegetable': 'carrot', 'meat': 'chicken'}

2. Handling Duplicate Values

If the original dictionary has duplicate values, use collections.defaultdict to map each value to a list of keys.

Example:

from collections import defaultdict

original_dict = {
    "apple": "fruit",
    "banana": "fruit",  # Duplicate value "fruit"
    "carrot": "vegetable"
}

# Create a defaultdict to store lists of keys
inverted_dict = defaultdict(list)

for key, value in original_dict.items():
    inverted_dict[value].append(key)

# Convert to a regular dictionary (optional)
inverted_dict = dict(inverted_dict)

print(inverted_dict)

Output:

{'fruit': ['apple', 'banana'], 'vegetable': ['carrot']}

3. Handling Non-Hashable Values

If the original dictionary’s values are non-hashable (e.g., lists), convert them to a hashable type (e.g., tuples) before inversion.

Example:

original_dict = {
    "list1": [1, 2, 3],
    "list2": [4, 5, 6],
    "list3": [1, 2, 3]  # Duplicate value [1, 2, 3]
}

# Convert lists to tuples and invert
inverted_dict = defaultdict(list)
for key, value in original_dict.items():
    hashable_value = tuple(value)
    inverted_dict[hashable_value].append(key)

inverted_dict = dict(inverted_dict)

print(inverted_dict)

Output:

{(1, 2, 3): ['list1', 'list3'], (4, 5, 6): ['list2']}

4. One-Liner for Unique Values

For a concise inversion when values are unique:

original_dict = {"a": 1, "b": 2, "c": 3}
inverted_dict = dict(zip(original_dict.values(), original_dict.keys()))

print(inverted_dict)  # {1: 'a', 2: 'b', 3: 'c'}

Key Considerations

  1. Uniqueness: Ensure values are unique if using the simple inversion method.
  2. Hashability: Values must be hashable (e.g., strings, numbers, tuples) to serve as keys.
  3. Order Preservation: Use collections.OrderedDict (Python 3.7+) if maintaining insertion order is important.

Summary

ScenarioMethod
Unique values{v: k for k, v in original_dict.items()}
Duplicate valuesdefaultdict(list) to map values to lists of keys.
Non-hashable valuesConvert values to hashable types (e.g., tuples) before inversion.

By choosing the appropriate method, you can reliably invert dictionaries in Python while handling edge cases like duplicates and non-hashable values.

Leave a Reply

Your email address will not be published. Required fields are marked *