RUNTIME VALUE CONVERSIONS
Build lists from supported iterables with multiple generators, filters, and unpacking. These forms use runtime value conversion.
def even_squares(limit: int) -> list[int]:
return [value * value for value in range(limit) if value % 2 == 0]
even_squares(6) returns [0, 4, 16]. The result expression runs only for elements that pass every filter. An empty iterable produces an empty list.
def pairs(limit: int) -> list[tuple[int, int]]:
return [(left, right)
for left in range(limit)
for right in range(left)
if right % 2 == 0]
pairs(4) returns [(1, 0), (2, 0), (3, 0), (3, 2)]. Generators run in written order like nested loops. Inner iterables may depend on earlier target values.
def select_rows(rows: list[tuple[str, int]]) -> list[str]:
return [name + ": " + str(count)
for name, count in rows
if count > 0
if name != ""]
For [("apple", 2), ("", 3), ("pear", 0)], the result is ["apple: 2"]. Use a fixed target shape with a matching element count; starred targets are unsupported.
def main() -> int:
value = 99
selected = [value for value in range(4) if value > 1]
print(value, selected[0], selected[1])
return 0
The output is 99 2 3. Comprehension targets have a separate scope and do not replace the surrounding local variable. Expressions and filters preserve their written evaluation order. Lambdas created inside a comprehension capture its live target cells; see Late binding.
Iterate over strings, lists, tuples, and ranges. Strings produce one-character strings. Results may contain mixed values, nested lists/tuples, class instances, or lambdas, subject to any declared result annotation.
List comprehensions allocate their result in the C context. Result size, nested iterations, and annotation checks consume the same memory and work budgets as ordinary runtime operations. Generator expressions, set/dictionary comprehensions, async generators, and arbitrary custom iterators are unsupported.