Python Arena
Step 4 of 4

Comprehensions instead of loops

Many loops you've written follow the same recipe: start with an empty list, go through a series, maybe check a condition, and append one value per round. Every loop like that can become a comprehension. Each part of the loop has its place:

long_names = []
for name in names:
    if len(name) > 4:
        long_names.append(name.upper())

long_names = [name.upper() for name in names if len(name) > 4]

What was appended moves to the front, the for line stays in the middle, and the if goes to the end.

Your own functions inside

When the expression needs several lines of work, write a function for it and call the function in the comprehension:

def grade(points):
    if points >= 90:
        return "A"
    if points >= 75:
        return "B"
    return "C"


points = [95, 80, 62, 77]
print([grade(p) for p in points])
Output
['A', 'B', 'C', 'B']

The comprehension stays short and readable, and the function can be tested on its own.

Lists, tuples and objects as items

The items can be anything, and so can the values you make from them. Here the items are lists and the new items are tuples:

In the Python interpreter
>>> table = [[3, 8, 1], [5], [9, 2]]
>>> [len(row) for row in table]
[3, 1, 2]
>>> [max(row) for row in table]
[8, 5, 9]
>>> [(n, n * n) for n in range(1, 4)]
[(1, 1), (2, 4), (3, 9)]

Items that are objects work the same way: [book.title for book in books] makes a list of the books' titles.

Two lists side by side

To combine two lists of the same length item by item, go through the indexes with range(len(...)):

prices = [3, 10, 2]
amounts = [4, 1, 5]
totals = [prices[i] * amounts[i] for i in range(len(prices))]
print(totals)
Output
[12, 10, 10]

Counting and adding up

A comprehension makes a list, and the functions you know for lists work on it right away. len of a filtered list counts the items that pass, and sum adds the values up:

In the Python interpreter
>>> scores = [72, 45, 90, 38, 66]
>>> len([s for s in scores if s >= 50])
3
>>> sum([s for s in scores if s >= 50])
228

When to keep the loop

A comprehension is for building a list. When a loop does something else, such as printing, asking for input or updating several variables at once, keep the loop. And if a comprehension grows so long that you have to read it three times, a loop or a helper function is kinder to the next reader.

Your task

Challenge 1 of 3

The function below builds its list with a loop. Rewrite it so that it returns a list comprehension instead, without append. It should still return the names longer than four letters in capital letters, so the program prints:

['GRACE', 'LINUS']

Challenge 2

A quiz has a list of the right answers, and each player gives a list of answers in the same order. Write a function quiz_score(answers, key) that returns the number of answers that match the right answer in the same position. Use a list comprehension.

For example, this call:

print(quiz_score(["a", "c", "b", "d"], ["a", "b", "b", "d"]))

prints:

3

Challenge 3

Write a function price_tags(items) that gets a list of tuples, each with a product's name and its price, and returns a list of price tags as strings. A tag has the name, a colon, a space and the price with two decimals. Use a list comprehension.

For example, this program:

tags = price_tags([("tea", 2.5), ("bread", 3), ("jam", 4.25)])
for tag in tags:
    print(tag)

prints:

tea: 2.50
bread: 3.00
jam: 4.25