List comprehensions are an efficient way to process sequences and create lists from the results. However, some people may initially find them to have an unintuitive syntax, or may not be sure how to create complicated list comprehensions.
Slight formatting changes and a few examples may help make these handy structures more comprehensible.
A Basic Example
The simplest form of list comprehension consists of square brackets ([]) containing an expression, followed by a for clause. The result is a new list created from the evaluation of the expression.
words = ('away', 'from', 'the', 'things', 'of', 'man')
# Traditional approach
where_would_you_go = []
for word in words:
where_would_you_go.append(word.title())
print(where_would_you_go)
# ['Away', 'From', 'The', 'Things', 'Of', 'Man']
# List comprehension
where_would_you_go = [word.title() for word in words]
print(where_would_you_go)
# ['Away', 'From', 'The', 'Things', 'Of', 'Man']
Reformatting the list comprehension may make it easier to parse its constituent parts:
words = ('away', 'from', 'the', 'things', 'of', 'man')
where_would_you_go = [
word.title()
for word in words
]
print(where_would_you_go)
# ['Away', 'From', 'The', 'Things', 'Of', 'Man']
Getting Complicated
A list comprehension can contain zero or more for or if clauses after the initial expression and for clause. As the list comprehensions get more complicated, the utility of the alternative formatting approach may become apparent.
List Comprehension With a Conditional
martin_luther_king_jr = (
'The profit motive, when it is the sole basis of an economic system, '
'encourages a cutthroat competition and selfish ambition that '
'inspires men to be more concerned about making a living '
'than making a life.'
)
words = martin_luther_king_jr.split(' ')
# Traditional approach
the_sole_basis = []
for idx, word in enumerate(words):
if word in ('profit', 'cutthroat', 'selfish', 'living'):
the_sole_basis.append((idx, word))
print(the_sole_basis)
# [(1, 'profit'), (15, 'cutthroat'), (18, 'selfish'), (30, 'living')]
# List comprehension
the_sole_basis = [
(idx, word)
for idx, word in enumerate(words)
if word in ('profit', 'cutthroat', 'selfish', 'living')
]
print(the_sole_basis)
# [(1, 'profit'), (15, 'cutthroat'), (18, 'selfish'), (30, 'living')]
List Comprehension With an if...else
# Enable pretty-printing a Python object to a stream
from pprint import pprint as pp
john_f_kennedy = (
'Those who make peaceful revolution impossible will make '
'violent revolution inevitable.'
)
words = john_f_kennedy.split(' ')
# Traditional approach
inevitable = []
for word in words:
if word == 'inevitable.':
inevitable.append(word.upper())
else:
inevitable.append(word.title())
pp(inevitable)
# ['Those',
# 'Who',
# 'Make',
# 'Peaceful',
# 'Revolution',
# 'Impossible',
# 'Will',
# 'Make',
# 'Violent',
# 'Revolution',
# 'INEVITABLE.']
# List comprehension
inevitable = [
word.upper()
if word == 'inevitable.'
else
word.title()
for word in words
]
pp(inevitable)
# ['Those',
# 'Who',
# 'Make',
# 'Peaceful',
# 'Revolution',
# 'Impossible',
# 'Will',
# 'Make',
# 'Violent',
# 'Revolution',
# 'INEVITABLE.']
List Comprehension With Multiple if...else
# Enable pretty-printing a Python object to a stream
from pprint import pprint as pp
an_agent_to_infinite_regression = (
'It no longer matters who consider themselves the masters of events. '
'Events no longer obey their masters.'
)
words = an_agent_to_infinite_regression.split(' ')
# Traditional approach
retribution = []
for idx, word in enumerate(words):
if word in ('consider', 'events.'):
retribution.append(f'~~~{word}~~~')
elif idx == 12 or word == 'obey':
retribution.append(f'---{word}---')
else:
retribution.append(word)
pp(retribution)
# ['It',
# 'no',
# 'longer',
# 'matters',
# 'who',
# '~~~consider~~~',
# 'themselves',
# 'the',
# 'masters',
# 'of',
# '~~~events.~~~',
# 'Events',
# '---no---',
# 'longer',
# '---obey---',
# 'their',
# 'masters.']
# List comprehension
retribution = [
f'~~~{word}~~~'
if word in ('consider', 'events.')
else
f'---{word}---'
if idx == 12 or word == 'obey'
else
word
for idx, word in enumerate(words)
]
pp(retribution)
# ['It',
# 'no',
# 'longer',
# 'matters',
# 'who',
# '~~~consider~~~',
# 'themselves',
# 'the',
# 'masters',
# 'of',
# '~~~events.~~~',
# 'Events',
# '---no---',
# 'longer',
# '---obey---',
# 'their',
# 'masters.']
List Comprehension With Multiple for Loops
# Enable pretty-printing a Python object to a stream
from pprint import pprint as pp
the_world_is_falling_apart = [
('Merely', 'a', 'man'),
('trying', 'to', 'survive'),
('in', 'a', 'world'),
('that', 'has', 'proven'),
('his', 'worst', 'fears'),
('true,', 'time', 'and'),
('again.',)
]
# Traditional approach
magnus = []
for tuple_ in the_world_is_falling_apart:
for word in tuple_:
magnus.append(word)
pp(magnus)
# ['Merely',
# 'a',
# 'man',
# 'trying',
# 'to',
# 'survive',
# 'in',
# 'a',
# 'world',
# 'that',
# 'has',
# 'proven',
# 'his',
# 'worst',
# 'fears',
# 'true,',
# 'time',
# 'and',
# 'again.']
# List comprehension
magnus = [
word
for tuple_ in the_world_is_falling_apart
for word in tuple_
]
pp(magnus)
# ['Merely',
# 'a',
# 'man',
# 'trying',
# 'to',
# 'survive',
# 'in',
# 'a',
# 'world',
# 'that',
# 'has',
# 'proven',
# 'his',
# 'worst',
# 'fears',
# 'true,',
# 'time',
# 'and',
# 'again.']
Nested List Comprehensions
# Enable pretty-printing a Python object to a stream
from pprint import pprint as pp
hiragana_syllables = [
('ga', 'za', 'da', 'ba', 'pa'),
('gi', 'ji', 'ji', 'bi', 'pi'),
('gu', 'zu', 'zu', 'bu', 'pu'),
('ge', 'ze', 'de', 'be', 'pe'),
('go', 'zo', 'do', 'bo', 'po')
]
# Traditional approach
monographs_with_diacritics = []
for i in range(len(hiragana_syllables)):
row = []
for tuple_ in hiragana_syllables:
row.append(tuple_[i])
monographs_with_diacritics.append(row)
pp(monographs_with_diacritics)
# [['ga', 'gi', 'gu', 'ge', 'go'],
# ['za', 'ji', 'zu', 'ze', 'zo'],
# ['da', 'ji', 'zu', 'de', 'do'],
# ['ba', 'bi', 'bu', 'be', 'bo'],
# ['pa', 'pi', 'pu', 'pe', 'po']]
# List comprehension
monographs_with_diacritics = [
[
tuple_[i]
for tuple_ in hiragana_syllables
]
for i in range(len(hiragana_syllables))
]
pp(monographs_with_diacritics)
# [['ga', 'gi', 'gu', 'ge', 'go'],
# ['za', 'ji', 'zu', 'ze', 'zo'],
# ['da', 'ji', 'zu', 'de', 'do'],
# ['ba', 'bi', 'bu', 'be', 'bo'],
# ['pa', 'pi', 'pu', 'pe', 'po']]
Wrapping Up
List comprehensions are a powerful part of any Python toolkit. With a few tweaks, you can make them more legible, and having a handy examples reference can help when things get complicated.