Find first sequence item that matches a criterion
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Finding the first item in a sequence that matches a condition is one of the most common “small” programming tasks. In Python, the most idiomatic answers are either a plain for loop or next(...) with a generator expression. The best choice depends on whether you want readability, a default value, or slightly more compact code.
Start With the Simple Loop
The most explicit solution is still a for loop.
This is a strong default because it is easy to read, easy to debug, and naturally stops as soon as the first match is found.
The runtime is linear in the worst case, but it short-circuits on the first success, which is exactly what you want.
Use next for an Idiomatic One-Liner
Python also has a compact built-in pattern:
This works because the generator expression produces matching items lazily, and next returns the first one it sees. The second argument to next is the default returned when no match exists.
This is concise and idiomatic, especially when the predicate is small and obvious.
Understand the Default Value
The default argument matters because without it, next raises StopIteration when no item matches.
If None is a meaningful value in your data, use a different sentinel instead.
That avoids ambiguity between “no match” and “the match is literally None.”
Searching Objects, Not Just Numbers
The same pattern works well for dictionaries, dataclass instances, or any other iterable objects.
This is usually better than filtering the whole sequence when you only need the first matching item.
Avoid Building Unnecessary Lists
A common beginner approach is:
This works, but it scans the whole sequence and allocates a new list even though only the first match is needed. A generator expression or loop is more efficient because it stops early.
That distinction matters more when the sequence is large or when the predicate is expensive.
Consider the Sequence Type
If your data is already sorted or indexed in a special way, there may be faster domain-specific approaches. For example, a sorted numeric list might be searched with bisect, and a dictionary lookup might eliminate iteration entirely.
But for the general problem “find the first item matching a criterion,” iteration is the correct baseline because the criterion can be arbitrary code.
Choose Clarity Over Cleverness
A good rule is:
- use a
forloop when the logic is non-trivial or needs debugging - use
next((... for ... if ...), default)when the predicate is simple and the code benefits from compactness
Both are idiomatic. Neither is automatically “more Pythonic” in every context.
Common Pitfalls
A common mistake is using a list comprehension when you only need the first result. That wastes work and memory.
Another issue is forgetting the default argument to next, which leads to StopIteration when no match exists.
Developers also sometimes write clever but hard-to-read one-liners for predicates that really belong in a named function. If the condition is complicated, a loop is often clearer.
Finally, be deliberate about the “no match” value. Returning None is fine only if it cannot be mistaken for a valid result.
Summary
- A plain
forloop is the clearest general solution for finding the first matching item. - '
next((item for item in sequence if condition), default)is the compact idiomatic alternative.' - Use a default value with
nextunless you explicitly wantStopIteration. - Prefer lazy search to building a full list of matches.
- Pick the style that keeps the predicate and fallback behavior easiest to understand.

