nums = [1, 2, 3, 4, 5]
squares = [n * n for n in nums]
squares
#> [1, 4, 9, 16, 25]13 Comprehension & Others
13.1 List Comprehension
13.1.1 Syntax
[expression for item in iterable if condition]Longer version:
[expression for item1 in iterable1 if condition1
for item2 in iterable2 if condition2
...
for itemN in iterableN if conditionN ]result = []
for item1 in iterable1:
if condition1:
for item2 in iterable2:
if condition2:
...
for itemN in iterableN:
if conditionN:
result.append(expression)13.1.2 Basic
Comprehension with filter
numbers = [1, 2, 3, 4, 5]
[n ** 2 for n in numbers if n % 2 == 0]
#> [4, 16]ls = ["a", "b", "c"]
# Equivalent
[x.upper() for x in ls]
#> ['A', 'B', 'C']
[str.upper(x) for x in ls]
#> ['A', 'B', 'C']13.1.3 Multiline Comprehension
For readibility:
def double_short_words(words):
return [
word + word
for word in words
if len(word) < 5
]13.1.4 Nested Compreshension
colors = ["orange", "purple", "pink"]
toys = ["bike", "basketball", "skateboard", "doll"]
[ color + " " + toy
for color in colors
for toy in toys ]
#> ['orange bike', 'orange basketball', 'orange skateboard', 'orange doll', 'purple bike', 'purple basketball', 'purple skateboard', 'purple doll', 'pink bike', 'pink basketball', 'pink skateboard', 'pink doll']13.1.5 Using _ varible
d = [1, 2]
l = [list(d) for _ in d]
l
#> [[1, 2], [1, 2]]13.1.6 Ex 1: List of Dict
portfolio = [
{'name': 'IBM', 'shares': 100, 'price': 91.1 },
{'name': 'MSFT', 'shares': 50, 'price': 45.67 },
{'name': 'HPE', 'shares': 75, 'price': 34.51 },
{'name': 'CAT', 'shares': 60, 'price': 67.89 },
{'name': 'IBM', 'shares': 200, 'price': 95.25 }
]Collect all names
names = [s['name'] for s in portfolio]
names
#> ['IBM', 'MSFT', 'HPE', 'CAT', 'IBM']Find all entries with more than 100 shares [‘IBM’]
more100 = [s['name'] for s in portfolio if s['shares'] > 100 ]
more100
#> ['IBM']Find the total shares*price
cost = sum([s['shares']*s['price'] for s in portfolio])
cost
#> 37105.15Collect (name, shares) tuples
name_shares = [ (s['name'], s['shares']) for s in portfolio ]
name_shares
#> [('IBM', 100), ('MSFT', 50), ('HPE', 75), ('CAT', 60), ('IBM', 200)]13.1.7 Ex 2: Wrapping Function
def toint(x):
try:
return int(x)
except ValueError:
return Nonevalues = [ '1', '2', '-4', 'n/a', '-3', '5' ]
data1 = [ toint(x) for x in values ]
print(data1)
#> [1, 2, -4, None, -3, 5]
data2 = [ toint(x) for x in values if toint(x) is not None ]
print(data2)
#> [1, 2, -4, -3, 5]Using :=
data3 = [ v for x in values if (v:=toint(x)) is not None ]
print(data3)
#> [1, 2, -4, -3, 5]
data4 = [ v for x in values if (v:=toint(x)) is not None and v >= 0 ]
print(data4)
#> [1, 2, 5]13.2 Set & Dict Comprehension
13.2.1 Set Comprehension
A set of distinct values
# Set comprehension
names = { s['name'] for s in portfolio }
names
#> {'HPE', 'MSFT', 'CAT', 'IBM'}13.2.2 Dict Comprehension
prices = { s['name']:s['price'] for s in portfolio }
prices
#> {'IBM': 95.25, 'MSFT': 45.67, 'HPE': 34.51, 'CAT': 67.89}dd = {"a": "aa", "b": "bb"}
{k: v for k, v in dd.items()} # Dict
#> {'a': 'aa', 'b': 'bb'}
[k for k in dd.keys()] # Keys
#> ['a', 'b']
[v for v in dd.values()] # Values
#> ['aa', 'bb']13.3 map() Function
map(function, iterable)
map() applies a function to all the items in an input list. It returns a map object (an iterator) of the results after applying the given function to each item of the given iterable (list, tuple etc.).
numbers = [1, 2, 3, 4, 5]
squares = map(lambda x: x**2, numbers)
list(squares) # Converting the map object to a list
#> [1, 4, 9, 16, 25]13.4 Differences and When to Use
- Readability: List comprehensions are often more readable and succinct, especially for simple operations or when filtering conditions are involved.
- Performance: Both list comprehensions and
map()are faster than a for loop. However, for very large data sets,map()can be more memory-efficient (since it returns an iterator), but the difference is often negligible. - Function Application: If you’re applying an existing function (especially a more complex one),
map()can be more convenient. For operations that can be expressed as a single expression, or where you need conditional logic (like filtering), a list comprehension is often the better choice. - Return Type:
map()returns a map object (iterator), which you often need to convert back to a list or another iterable type. List comprehensions return a list directly.
In summary, use list comprehensions when you need a readable and concise way to generate a new list by applying an expression to each item in an iterable, possibly with filtering. Use map() when you need to apply an already-defined function to each item in an iterable and are okay with receiving an iterator as the result.