Generator Expressions and Lazy Evaluation
The expression is what Python does with each item.
From Loop to Comprehension
Building a new list from an existing list often follows the same pattern: create an empty result list, iterate through the source data, transform each item, and append the transformed value. A list comprehension expresses that complete pattern in one readable line. The source material for this article focuses on list comprehensions and their element-by-element data flow.
Matching the Loop Structure
numbers = []
for x in ["42", "65", "12"]:
numbers.append(int(x))
result = sum(numbers)- 1numbers = [] initializes an empty list for the results.
- 2The for clause visits each string in the source list.
- 3
int(x)transforms the current string into an integer. - 4
numbers.append(int(x))adds the transformed integer to the result list. - 5
sum(numbers)adds the integers in the completed list.
119The basic structure is [expression for variable in iterable]. The expression is what Python does with each item. The for clause identifies the loop variable and the source of the items. The square brackets indicate that a new list is being created and populated. In the longer loop, the empty-list initialization and append call are explicit. In the comprehension, those operations are represented by the square-bracket structure and the expression position.
Tracing Each Value
What do you think happens?
What list will this comprehension produce?
Reveal answer
[42, 65, 12]
Each source string enters the comprehension one at a time. int(x) converts "42" to 42, "65" to 65, and "12" to 12. The converted values are collected in a new list.
Converting numeric strings
Convert the strings "42", "65", and "12" to integers and collect the results.
- 1First item
The loop variable x holds "42". The expression
int(x)produces 42, which enters the new list. - 2Second item
The loop variable x holds "65". The expression
int(x)produces 65, which enters the new list. - 3Third item
The loop variable x holds "12". The expression
int(x)produces 12, which enters the new list.
The completed list is [42, 65, 12]. Summing its values produces 119.
The data flow is sequential: a source item becomes the current value of x, int(x) transforms that value, and the transformed value is added to the result list. This repeats for every source item. Thinking through the values one at a time is useful when reading a comprehension or checking whether its expression does what you intend.
Filtering with Conditions
A condition can be added after the iterable to filter which transformed values enter the result. The structure becomes [expression for variable in iterable if condition]. Python considers each source item, evaluates the expression used for the result and the condition as shown in the comprehension, and includes only the items that satisfy the condition.
[65, 88]For the source values 42, 65, 12, and 88, only 65 and 88 satisfy int(x) > 50. Those two values are collected, while 42 and 12 are excluded. The condition appears at the end of the comprehension, which is the standard filtering form described in the source material.
Debugging by Expansion
A comprehension can be difficult to inspect when its expression or condition is not behaving as expected. The most reliable debugging method is to expand it into the longer for-loop pattern. Write the empty-list initialization, place the transformation inside the loop, apply the condition explicitly, and append the result. Then inspect which source items reach each step.
Common mistake Forgetting the expression that creates each result value.
What it looks like[for x in values]Why it failsA list comprehension needs an expression describing what should be placed in the new list.
Do this insteadPut the transformation before the for clause, such as [int(x) for x in values].
Common mistake Placing the condition in the wrong conceptual position.
What it looks likeThe filtering condition is treated as the result expression.
Why it failsThe expression determines the value collected, while the if condition determines whether an item is included.
Do this insteadUse the structure [expression for variable in iterable if condition].
Common mistake Keeping a comprehension compact after its logic becomes difficult to read.
What it looks likeA comprehension with multiple nested clauses or complex conditions.
Why it failsThe source guidance recommends a traditional for loop when the logic has multiple steps, conditional branches, or debugging output.
Do this insteadExpand the operation into a for loop when the longer form is clearer and more maintainable.
Choosing the Clearer Form
| Use a list comprehension | Use a traditional for loop |
|---|---|
| A simple, single transformation is applied to each item. | The loop body has multiple steps. |
| The result fits comfortably on one or two lines. | The logic includes complex conditional branches. |
| The comprehension is immediately clear to the reader. | You need to print debugging information during iteration. |
| A new list is being built from existing data. | Expanding the code would make the operation easier to understand and maintain. |
Choose the form that makes the operation easiest to read.
Use a list comprehension for a straightforward transformation or filtering operation that remains readable on one or two lines. Prefer a traditional for loop when the operation requires several steps, different transformations based on values, complex conditions, or debugging output. Conciseness is useful only when the result remains clear.
Practice the Mapping
Take the comprehension [int(x) for x in ["42", "65", "12", "88"] if int(x) > 50]. Expand it into a traditional for loop with an empty result list, an if statement, and an append operation. Then identify the expression, loop variable, iterable, and condition in the original comprehension.
Hints
- Start with result = [].
- Loop through the four strings.
- Test
int(x)> 50 before appending. - Append
int(x)only when the condition is true.
Key Takeaways
- 1A list comprehension condenses empty-list initialization, iteration, transformation, and append operations into a single expression.
- 2The structure [expression for variable in iterable] maps directly to the corresponding parts of a for loop.
- 3A condition can be added with [expression for variable in iterable if condition] to filter which results are included.
- 4Tracing one source item at a time helps you understand the transformation and debug the comprehension.
- 5Use comprehensions for simple, readable operations; use for loops when the logic has multiple steps or becomes difficult to read.
At a glance
- List comprehensions provide a compact alternative to the common for-loop pattern for building a new list.
- The expression comes first, followed by the loop variable and iterable; an optional condition filters included results.
- Each source item flows through the expression and contributes a value to the result list.
- Expanding a comprehension into a for loop is a practical way to debug it.
- Readability determines whether a comprehension or a traditional loop is the better choice.