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)
[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)
[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 wordsworks like the first line of aforloop, without the colon. It goes through the series one item at a time.- The expression before the
for, herelen(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:
>>> 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]
File "main.py", line 2
doubled = [for n in numbers: n * 2]
^^^
SyntaxError: invalid syntaxThe fix is [n * 2 for n in numbers]: first what you want, then where it comes from.