Python Arena
Step 2 of 4

Picking items with if

Sometimes the new list should have only some of the items. With a loop you'd put an if inside it:

scores = [72, 45, 90, 38, 66]
passed = []
for score in scores:
    if score >= 50:
        passed.append(score)
print(passed)
Output
[72, 90, 66]

A list comprehension can do the same. The condition goes at the end:

scores = [72, 45, 90, 38, 66]
passed = [score for score in scores if score >= 50]
print(passed)
Output
[72, 90, 66]

The shape is now:

[expression for item in series if condition]

Only the items for which the condition is True make it into the new list. The others are skipped, so the new list can be shorter than the original, or even empty. This is called filtering. Here the expression is just score, so the items that pass go in as they are.

Filter and change at the same time

The expression can still change the items that pass the filter:

In the Python interpreter
>>> numbers = [3, 8, 5, 12, 7, 4]
>>> [n for n in numbers if n % 2 == 0]
[8, 12, 4]
>>> [n * n for n in numbers if n % 2 == 0]
[64, 144, 16]
>>> [n for n in numbers if n > 100]
[]

In the second comprehension, 3, 5 and 7 are never squared at all. They're left out before the expression is worked out.

A filter as a guard

That order matters when the expression can fail. Here each team shares 40 pizza slices, and the comprehension works out how many slices each person gets. But two teams have 0 people, a mistake in the data, and dividing by 0 stops the program:

team_sizes = [4, 0, 5, 0, 10]
pizza_slices = [40 // size for size in team_sizes]
print(pizza_slices)
Python stops with
Traceback (most recent call last):
  File "main.py", line 2, in <module>
    pizza_slices = [40 // size for size in team_sizes]
                    ~~~^^~~~~~
ZeroDivisionError: division by zero

A filter fixes it. For each size, Python checks the condition first, and only a size that passes gets as far as 40 // size:

team_sizes = [4, 0, 5, 0, 10]
pizza_slices = [40 // size for size in team_sizes if size != 0]
print(pizza_slices)
Output
[10, 8, 4]

The condition can be anything that gives True or False, including conditions joined with and and or, and in:

In the Python interpreter
>>> words = ["apple", "fig", "banana", "kiwi", "cherry"]
>>> [w for w in words if len(w) > 3 and "a" in w]
['apple', 'banana']

Your task

Challenge 1 of 3

Fill in the blank so that freezing holds only the temperatures below zero. The program should print:

[-2, -7, -1]

Challenge 2

What does this program print? Type each line it prints.

Challenge 3

Write a function words_with(words, letter) that returns a new list of the words that contain the given letter, in their original order. Use a list comprehension.

For example, this call:

print(words_with(["python", "java", "rust", "ruby"], "u"))

prints:

['rust', 'ruby']