Learning LibraryCore Coding LibraryTeens

List Comprehensions in Python: build a list in one line

Building a list with a loop takes three lines: make an empty list, loop, append. A list comprehension does the same thing in one clear line.

The big idea

A list comprehension builds a list from a loop in a single expression: [expr for item in iterable].

See it in code

1The basics

The shape is [expr for item in iterable]. Here we build the x-positions of a six-wide wave — one value per column — in a single line:

python
xs = [55 + col * 74 for col in range(6)]
print(xs)
Run it — six positions, built at once:
[55, 129, 203, 277, 351, 425]

Read it as a sentence: '55 + col * 74 for each col in range(6).' No empty list, no append — the whole list appears at once.

2A step further

Add an if at the end to filter. From those positions, keep only the ones on the left half of the screen:

python
xs = [55 + col * 74 for col in range(6)]
left = [x for x in xs if x < 250]
print(left)
Run it — only the positions under 250 survive:
[55, 129, 203]

The if x < 250 kept three of the six. Now let's turn each position into a real Enemy — same one-line pattern.

3In our world

The long way to build a wave is a loop that appends. The comprehension [Enemy(x, 90) for x in range(40, 480, 74)] says the same thing left to right: make an `Enemy(x, 90)` for each `x` in that range. It produces the whole list at once:

python
from game import Stage, Enemy

screen = Stage.create()
Stage.clear(screen)

wave = [Enemy(x, 90) for x in range(40, 480, 74)]
print("Built", len(wave), "enemies in one line")

for enemy in wave:
    enemy.draw(screen)
Run it — one line builds the whole wave:
Built 6 enemies in one line
A row of six purple enemy sprites evenly spaced near the top of a dark play area.

Read it as the sentence it is: 'an Enemy at (x, 90) for each x in the range.' Same pattern as the warm-ups — and you can add the same if filter to keep only some, transforming each item as you go.

The same idea, everywhere

Comprehensions are the Pythonic way to transform data: [p * 1.1 for p in prices] to adjust a series, [c.upper() for c in bases] to normalize DNA, [w for w in words if len(w) > 3] to filter. They're shorter and usually faster than the append loop — and dictionaries and sets have their own comprehension forms too.

Try it yourself

Add a filter to keep only even columns: [Enemy(x, 90) for x in range(40, 480, 74) if x < 300]. Then build a list of squares, [n * n for n in range(6)], and print it.

The common mistake

Cramming too much in, or reaching for a comprehension when you only need side effects. If the body is complex or you're just calling draw() on each item, a plain for loop reads better. Comprehensions are for building a list, not for doing work and throwing the result away.

What it unlocks

Comprehensions build on for loops, range(), and lists, and make wave-building and data prep concise.