Back to Blog
Python

Python Dictionary Comprehension Condition

python dictionary comprehension condition: Learn how to apply conditions in Python dictionary comprehensions to filter, transform, and build dictionaries efficiently w...

dictionary comprehensionconditional logicPython syntaxdata filteringdict comprehensionPython performance
Illustration of a dictionary with a funnel filter, representing conditional dictionary comprehension in Python.

python dictionary comprehension condition requires a clear understanding of the core syntax, runtime behavior, and practical implementation patterns demonstrated in the examples below.

When you need to construct a dictionary from an iterable, you often want to include only certain key-value pairs. A condition inside a dictionary comprehension lets you filter entries at construction time, avoiding a separate loop and an intermediate data structure. The general form is {key_expr: value_expr for item in iterable if condition}. The if clause is evaluated for each item, and only items for which it returns True produce a key-value pair in the resulting dictionary.

Basic Filtering with an if Clause

Consider a list of tuples where each tuple contains a name and a score. You want a dictionary that maps names to scores only for scores above a threshold.

scores = [("alice", 82), ("bob", 74), ("carol", 91), ("dave", 68)] passed = {name: score for name, score in scores if score >= 75} print(passed) # {'alice': 82, 'carol': 91}

The condition score >= 75 is evaluated for each tuple. When it is True, the tuple's name and score become a key-value pair. This is equivalent to a loop that checks the condition and inserts into a dictionary, but the comprehension is more concise and keeps the logic in one place.

Transforming Values with if-else

Sometimes you want to include every key but apply a different value depending on a condition. Use a conditional expression (ternary) inside the value expression.

words = ["apple", "banana", "cherry", "date"] length_label = {word: ("long" if len(word) > 5 else "short") for word in words} print(length_label) # {'apple': 'short', 'banana': 'long', 'cherry': 'long', 'date': 'short'}

The ternary "long" if len(word) > 5 else "short" is evaluated for each word. This pattern is useful when you need to keep all keys but vary the stored value based on a rule. Note that the if clause and the ternary serve different purposes: the if clause filters which items are included, while the ternary changes the value for every included item.

Combining Multiple Conditions

You can use and, or, and parentheses to build complex filter logic. For example, keep entries where the key starts with a certain prefix and the value meets a numeric threshold.

inventory = {"apple": 12, "apricot": 4, "banana": 7, "avocado": 9} selected = {k: v for k, v in inventory.items() if k.startswith("a") and v > 5} print(selected) # {'apple': 12, 'avocado': 9}

Multiple conditions are evaluated left to right, and short-circuiting applies just as in ordinary boolean expressions. This keeps the comprehension readable without forcing you to precompute a separate list of filtered keys.

Performance and Memory Considerations

A dictionary comprehension runs at Python's C speed for the iteration and dictionary insertion, which is generally faster than a manual loop with if and assignment. It also avoids creating an intermediate list of filtered tuples, which reduces memory pressure when working with large iterables. However, the condition expression itself is still executed in Python, so a complex condition with expensive function calls can dominate the runtime. If the condition involves a lookup in another dictionary or a costly computation, consider precomputing values in a local variable to avoid repeated work.

# Avoid recomputing a function inside the condition allowed = set(["apple", "banana", "cherry"]) result = {k: v for k, v in data.items() if k in allowed}

Here allowed is a set, making membership tests O(1). If you used a list, the in check would be O(n) for each item, turning the comprehension into O(n*m). The comprehension itself does not change algorithmic complexity, but choosing the right data structure for the condition does.

Common Mistakes and How to Avoid Them

A frequent error is trying to modify the dictionary being built while iterating over the source. Since the comprehension constructs a new dictionary, this is not an issue. However, referencing the dictionary being built inside the condition or value expression is not possible because the name is not bound until the comprehension completes.

Another mistake is forgetting that the if clause filters items before the value expression is evaluated. If the value expression relies on an attribute or method that is not present on filtered-out items, you must ensure the condition excludes those items first. For example, if you have a list of objects and you call .name on each, but some objects are None, the condition must check for None before the value expression runs.

items = [{"name": "a", "val": 1}, None, {"name": "b", "val": 2}] # This fails: None has no .get # result = {x["name"]: x["val"] for x in items if x["val"] > 0}

The corrected version checks that x is not None first:

result = {x["name"]: x["val"] for x in items if x is not None and x["val"] > 0}

Because and short-circuits, the second condition is only evaluated when x is not None.

Using Conditions with Dictionary Views and Nested Comprehensions

Conditions work with any iterable, including dictionary views. When you iterate over .items(), you can filter on both keys and values. This is common when cleaning up a dictionary by removing entries that fail a predicate.

original = {"a": 1, "b": -2, "c": 3} positive = {k: v for k, v in original.items() if v > 0}

You can also nest comprehensions, though readability suffers. A nested dictionary comprehension with a condition is useful when building a dict of dicts from grouped data, but consider whether a helper function would be clearer.

groups = [("fruit", "apple"), ("fruit", "banana"), ("veg", "carrot")] grouped = {cat: {name for _, name in groups if _ == cat} for cat, _ in groups}

This produces {'fruit': {'apple', 'banana'}, 'veg': {'carrot'}}. The inner comprehension filters items by category, and the outer comprehension iterates over unique categories. While functional, the repeated groups iteration makes it O(n^2). For larger data, a loop with defaultdict(set) would be more efficient and easier to maintain.

When a Dictionary Comprehension Is Not the Right Choice

The comprehension is concise when the key and value expressions are straightforward. If you need to perform side effects, such as logging or updating an external counter, a regular for loop is clearer because comprehensions are meant for pure transformations. Also, if the condition depends on the state of the dictionary being built (for example, checking whether a key already exists), you cannot reference the dictionary inside the comprehension. In such cases, build the dictionary incrementally with a loop.

# Cannot check membership in the result dict inside a comprehension result = {} for item in data: if item.key not in result: result[item.key] = item.value

The comprehension syntax is optimized for filtering and mapping, not for stateful accumulation. Recognizing this boundary helps you choose the right tool without forcing a comprehension into every situation.

python dictionary comprehension condition: Practical Usage a | RYUSLOG DEV