推导式简介
- 作用:简洁的语法生成一个数据结构:列表、字典、集合等
- 注解:推导式属于Python独有的语法,目的是为了让代码更简洁,如果觉得不想用过完全可以不用。
列表推导式
参考 https://docs.python.org/zh-cn/3.9/tutorial/datastructures.html#list-comprehensions列表推导式创建列表的方式更简洁。常见的用法为,对序列或可迭代对象中的每个元素应用某种操作,用生成的结果创建新的列表;或用满足特定条件的元素创建子序列。
普通列表推导式
例如,创建平方值的列表:
>> squares = []
>> for x in range(10):
... squares.append(x**2)
...
>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
注意,循环结束后,创建(或重写)的名为
x
的变量仍然存在。>> x
9
等价于:
squares = [x**2 for x in range(10)]
注意,循环结束后,创建(或重写)的名为
x
的变量不存在。>> x
NameError: name 'x' is not defined
列表推导式的方括号内包含以下内容:一个表达式,后面跟一个
for
子句,然后,是零个或多个for
或if
子句。结果是新的列表,由对表达式依据后面的for
和if
子句的内容进行求值计算而得出。 举例来说,以下列表推导式将两个列表中不相等的元素组合起来:
>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
等价于:
>>> combs = []
>>> for x in [1,2,3]:
... for y in [3,1,4]:
... if x != y:
... combs.append((x, y))
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
# [i*2+10 for i in range(10) if i%3==0]
# 等效于
l = []
for i in range(10):
if i % 3 == 0:
l.append(i * 2 + 10)
In[1]: [i * 2 + 10 for i in range(10) if i % 3 == 0]
Out[1]: [10, 16, 22, 28]
In [2]: [i*2 if i%3==0 else i for i in range(10) ]
Out[2]: [0, 1, 2, 6, 4, 5, 12, 7, 8, 18]
In[3]: [i for i in range(5) if i % 2 == 0]
Out[3]: [0, 2, 4]
In[4]: [i for i in range(5) if i % 2 == 0 and not i == 2]
Out[4]: [0, 4]
嵌套的列表推导式
参考 https://docs.python.org/zh-cn/3.9/tutorial/datastructures.html#nested-list-comprehensions
>>> matrix = [
... [1, 2, 3, 4],
... [5, 6, 7, 8],
... [9, 10, 11, 12],
... ]
下面的列表推导式可以转置行列:
>>> [[row[i] for row in matrix] for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
如上节所示,嵌套的列表推导式是基于跟随其后的 for
进行求值的,所以这个例子等价于:
>>> transposed = []
>>> for i in range(4):
... transposed.append([row[i] for row in matrix])
...
>>> transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
反过来说,也等价于:
>>> transposed = []
>>> for i in range(4):
... # 下面3行实现了嵌套的list
... transposed_row = []
... for row in matrix:
... transposed_row.append(row[i])
... transposed.append(transposed_row)
...
>>> transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
集合推导式
返回一个集合
In [1]: s={i*2+10 for i in range(10) if i%3==0}
In [2]: type(s)
Out[2]: set
In [3]: s
Out[3]: {10, 16, 22, 28}
【字典推导】
返回一个字典
In [4]: dict={i:i*2+10 for i in range(10) if i%3==0}
In [5]: type(dict)
Out[5]: dict
In [6]: dict
Out[6]: {0: 10, 3: 16, 6: 22, 9: 28}
【生成器推导式】
参考 https://docs.python.org/zh-cn/3.9/tutorial/classes.html#generator-expressions
作用:列表生成器如果数据过大,会造成内存压力,此时可用生成器推导式来处理
In [45]: a=(i*2+10 for i in range(10) if i%3==0)
In [46]: a
Out[46]: <generator object <genexpr> at 0x000000000445CC60>
In [47]: type(a)
Out[47]: generator
In [48]: a.next()
Out[48]: 10
In [49]: a.next()
Out[49]: 16
In [50]: a.next()
Out[50]: 22
In [51]: a.next()
Out[51]: 28
总结
一些更复杂的用法,可自行组合