Python Arena
Step 1 of 4

A new list from an old one

Many programs take a list and make a new list out of it: prices with tax added, names in capital letters, the length of every word. So far you've done it with a loop that starts from an empty list and appends one item per round:

words = ["tea", "coffee", "cocoa", "water"]
lengths = []
for word in words:
    lengths.append(len(word))
print(lengths)
Output
[3, 6, 5, 5]

That's three lines to say one thing: "the length of each word". Python has a shorter way to say it, a list comprehension:

words = ["tea", "coffee", "cocoa", "water"]
lengths = [len(word) for word in words]
print(lengths)
Output
[3, 6, 5, 5]

How to read it

A list comprehension has this shape:

[expression for item in series]
  • The square brackets say that the result is a new list.
  • for word in words works like the first line of a for loop, without the colon. It goes through the series one item at a time.
  • The expression before the for, here len(word), says what goes into the new list for each item.

Read it out loud from the left: "the length of word, for each word in words". The new list has exactly as many items as the series, in the same order. The original list doesn't change: the comprehension only reads it.

Any expression will do

The expression can be a calculation, a method call, a conversion or a call to a function: anything that gives a value. The series can be anything a for loop can go through, such as a list or a range:

In the Python interpreter
>>> numbers = [4, 7, 10]
>>> [n * 10 for n in numbers]
[40, 70, 100]
>>> [str(n) for n in numbers]
['4', '7', '10']
>>> names = ["ada", "linus", "grace"]
>>> [name.capitalize() for name in names]
['Ada', 'Linus', 'Grace']
>>> [n * n for n in range(1, 6)]
[1, 4, 9, 16, 25]

The second one shows that the new items don't have to be of the same type as the old ones: numbers went in, strings came out. The third uses the string method capitalize, which gives the string with its first letter in capitals and the rest in small letters, so "aDA" would become 'Ada' too.

A function can return a comprehension directly. There's no need to store it in a variable first:

def lengths_of(words):
    return [len(word) for word in words]

The expression comes first

The order matters. If you write it in the order of a loop, with the for first, Python can't read it:

numbers = [4, 7, 10]
doubled = [for n in numbers: n * 2]
Python stops with
  File "main.py", line 2
    doubled = [for n in numbers: n * 2]
               ^^^
SyntaxError: invalid syntax

The fix is [n * 2 for n in numbers]: first what you want, then where it comes from.

Your task

Challenge 1 of 3

Every order in the shop gets a shipping fee of 5 added to its price. Fill in the blank so the comprehension makes the list of prices with shipping. The program should print:

[17, 45, 9, 25]

Challenge 2

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

Challenge 3

Write a function shout(words) that returns a new list with each word in capital letters and an exclamation mark at the end. Use a list comprehension.

For example, shout(["hi", "stop", "go"]) returns ['HI!', 'STOP!', 'GO!'], so the program in the editor prints:

['HI!', 'STOP!', 'GO!']