Contents
30.4.1. 用列表推导取代map与filter¶
Python提供了一种特殊的写法,叫做推导(comprehension),可以简洁地迭代列表、字典和集合等数据结构,并根据迭代结果生成另一套数据。
Python把这种理念也运用到了函数上面,产生了生成器(generator),它可以让函数每次返回一系列值中的一个。凡是可以使用迭代器的任务都支持生成器函数。
假设我们要用列表中每个元素的平方值构建一份新的列表,传统的写法是采用for循环来写。
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
squares = []
for x in a:
squares.append(x**2)
print(squares)
这段代码可以改用列表推导来写。
# 列表推导式
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
squares = [x**2 for x in a]
print(squares)
当然也可以用map实现该功能。
alt = list(map(lambda x: x ** 2, a))
print(alt)
列表推导式还有一个地方比map好,就是它能方便地过滤原列表,把某些输入值对应的计算结果从输出结果中排除。
even_squares = [x**2 for x in a if x % 2 == 0]
even_squares
字典与几何也有相应的推导机制,分别叫字典推导与集合推导。
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_squares_dict = {x: x ** 2 for x in a if x % 2 == 0}
threes_cubed_set = {x ** 3 for x in a if x % 3 == 0}
print(even_squares_dict)
print(threes_cubed_set)
如果改用map与filter实现,那么还必须调用相应的构造器,这会让代码变得很长。
alt_dict = dict(map(lambda x: (x, x ** 2), filter(lambda x: x % 2 == 0, a)))
alt_set = set(map(lambda x: x ** 3, filter(lambda x: x % 3 == 0, a)))
assert even_squares_dict == alt_dict
assert threes_cubed_set == alt_set
要点:
列表推导要比内置的map与filter函数清晰,因为它不用另外定义lambda表达式。
列表推导可以很容易地跳过原列表中的某些数据,假如改用map实现,那么必须搭配filter才能实现。
字典与集合也可以通过推导来创建。