Concepts / Generator Expressions and Lazy Evaluation

Generator Expressions and Lazy Evaluation

The expression is what Python does with each item.

  • Programming

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

Code walkthrough
numbers = []
for x in ["42", "65", "12"]:
    numbers.append(int(x))

result = sum(numbers)
  1. 1
    numbers = [] initializes an empty list for the results.
  2. 2
    The for clause visits each string in the source list.
  3. 3
    int(x) transforms the current string into an integer.
  4. 4
    numbers.append(int(x)) adds the transformed integer to the result list.
  5. 5
    sum(numbers) adds the integers in the completed list.
python
Output
119
[new list beginsint(x)transformationfor x in sourceiteration]list completed
How do initialization, iteration, expression evaluation, and append operations in a for loop map onto a list comprehension?

The 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?

  • [42, 65, 12]

  • ["42", "65", "12"]

  • [119]

Reveal answer
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.

Source strings["42", "65", "12"]int(x)convert current itemResult list[42, 65, 12]one item at a timeconverted value
When is each value produced, and how does each source item move through the expression into the result list?
Worked example

Converting numeric strings

Convert the strings "42", "65", and "12" to integers and collect the results.

  1. 1
    First item

    The loop variable x holds "42". The expression int(x) produces 42, which enters the new list.

  2. 2
    Second item

    The loop variable x holds "65". The expression int(x) produces 65, which enters the new list.

  3. 3
    Third item

    The loop variable x holds "12". The expression int(x) produces 12, which enters the new list.

Result

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.

python
Output
[65, 88]
Current stringsource itemint(x) > 50filter testint(x)result expressionResult list[65, 88]inspecttruefalse: excludeadd transformed value
In what order does the comprehension inspect each item, apply the condition, transform the accepted value, and place it in the result list?

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.

python
  • Common mistake

    Forgetting the expression that creates each result value.

    What it looks like
    [for x in values]
    Why it fails

    A list comprehension needs an expression describing what should be placed in the new list.

    Do this instead

    Put 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 like

    The filtering condition is treated as the result expression.

    Why it fails

    The expression determines the value collected, while the if condition determines whether an item is included.

    Do this instead

    Use 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 like

    A comprehension with multiple nested clauses or complex conditions.

    Why it fails

    The source guidance recommends a traditional for loop when the logic has multiple steps, conditional branches, or debugging output.

    Do this instead

    Expand the operation into a for loop when the longer form is clearer and more maintainable.

Choosing the Clearer Form

Use a list comprehensionUse 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.

Best practice

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

MEDIUM

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

  1. 1
    A list comprehension condenses empty-list initialization, iteration, transformation, and append operations into a single expression.
  2. 2
    The structure [expression for variable in iterable] maps directly to the corresponding parts of a for loop.
  3. 3
    A condition can be added with [expression for variable in iterable if condition] to filter which results are included.
  4. 4
    Tracing one source item at a time helps you understand the transformation and debug the comprehension.
  5. 5
    Use 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.

Related concepts

More concepts starting with G