CodingNic

Python Lists

List Iteration and Comprehension

Python Lists 20 min read

List Iteration and Comprehension

Objectives

By the end of this chapter, you should be able to:

  • Iterate over lists and strings
  • Create and iterate over ranges
  • Use list comprehension to write concise loops
  • Use a nested comprehension to build a list of lists

💡 Why this matters: You’ll loop over collections constantly, and list comprehension is how experienced Python developers turn a multi-line loop into a single, readable line.

Looping with for...in

The standard way to loop over a list (or a string) is for element in collection:. Don’t forget the colon at the end of that line:

python
values = [1, 2, 3, 4]
for val in values:
    print(val)
# 1
# 2
# 3
# 4

for char in "awesome":
    print(char)
# a
# w
# e
# s
# o
# m
# e

Getting the Index Too: enumerate

When you need both the index and the value, wrap the collection in enumerate:

python
for idx, char in enumerate("awesome"):
    print(idx, char)
# 0 a
# 1 w
# 2 e
# 3 s
# 4 o
# 5 m
# 6 e

while Loops

Less common for iterating over a collection, but still useful:

python
i = 0
while i < 5:
    print(i)
    i += 1
# 0
# 1
# 2
# 3
# 4

Skipping and Stopping: continue and break

continue skips to the next iteration; break exits the loop entirely:

python
for num in [1, 2, 3, 4, 5, 6, 7]:
    if num % 2 == 0:
        continue
    elif num > 5:
        break
    print(num)
# 1
# 3
# 5

Even numbers hit continue and skip straight to the next iteration, before they ever reach print. 7 is the value that actually triggers break: it’s odd, so it passes the continue check, then 7 > 5 is True, so the loop exits immediately, before print(7) runs.

range

range(start, stop, step) generates a sequence of numbers without building a full list in memory, useful for anything that just needs to count. It’s not inclusive of stop:

python
for num in range(4, 10):
    print(num)
# 4
# 5
# 6
# 7
# 8
# 9

range also unpacks like any other sequence:

python
a, b, c, d = range(4)
a  # 0
b  # 1
c  # 2
d  # 3

Combined with chr() (which converts a number into its corresponding character), you can build an alphabet:

python
capital_letters = []
for num in range(65, 91):
    capital_letters.append(chr(num))
capital_letters
# ['A', 'B', 'C', ..., 'X', 'Y', 'Z']

Because a range doesn’t store every number in memory the way a list does, prefer it over a hardcoded list whenever you just need evenly-spaced numbers.

List Comprehension

List comprehensions build a new list in a single line, a much more concise alternative to writing out a full loop. The simplest form transforms every element in a collection:

python
[num ** 2 for num in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

[chr(num) for num in range(65, 91)]
# ['A', 'B', 'C', ..., 'X', 'Y', 'Z']

Add an if clause to filter which elements make it into the result. Here, in is used as a membership check: letter in ["a", "e", "i", "o", "u"] is a True/False question (“is letter one of these?”), which is different from the in used to start a for loop:

python
"a" in ["a", "e", "i", "o", "u"]  # True
"z" in ["a", "e", "i", "o", "u"]  # False

# without a comprehension
vowels = []
for letter in "awesome":
    if letter in ["a", "e", "i", "o", "u"]:
        vowels.append(letter)
# vowels == ['a', 'e', 'o', 'e']

# the same thing, as a comprehension
vowels = [letter for letter in "awesome" if letter in ["a", "e", "i", "o", "u"]]
# ['a', 'e', 'o', 'e']

Comprehensions combine naturally with other functions too. Here’s a comprehension nested inside len(), counting how many three-letter words are in a sentence:

python
len([word for word in "the quick brown fox jumps over the lazy dog".split(" ") if len(word) == 3])

For anything longer, split the comprehension across multiple lines for readability:

python
len([
    word
    for word in "the quick brown fox jumps over the lazy dog".split(" ")
    if len(word) == 3
])

The syntax takes some practice to read comfortably. Every comprehension follows the same shape: [expression for item in iterable if condition], where the if condition part is optional.

Nested List Comprehension: Building a List of Lists

A comprehension’s expression (the part before for) can be anything, including another whole list, which gives you a list of lists:

python
[[0, 1, 2] for _ in range(3)]
# [[0, 1, 2], [0, 1, 2], [0, 1, 2]]

Read this the same way as any other comprehension: for every value produced by range(3), put [0, 1, 2] into the result. The underscore _ is a common convention for “a loop variable I’m not actually going to use”: range(3) is only there to make the loop run three times, not because its values matter.

This is a genuinely different pattern from the filtering/transforming comprehensions above: instead of transforming each existing element, you’re repeating one fixed value a set number of times. Both are “list comprehension,” but it’s worth recognizing them as two distinct uses of the same syntax.

Try It

  1. Loop over a string with for...in, printing each character alongside its index using enumerate.
  2. Build a list of the squares of 0 through 9 using a comprehension.
  3. Use a comprehension with an if filter to pull every word longer than four letters out of a sentence of your choice.
  4. Use a nested comprehension to build a list containing 5 copies of the string "hi".

Recap

  • for...in is the standard way to loop; enumerate adds the index alongside each element.
  • range(start, stop, step) generates numbers without building a full list in memory, and excludes the stop value.
  • List comprehensions ([expression for item in iterable if condition]) replace many loops with a single, readable line.
  • A comprehension’s expression can be a whole list itself, giving you a list of lists: a repetition pattern, distinct from transforming or filtering existing elements.

Next lesson: put lists into practice with a set of exercises, all written using list comprehension.