推导式简介

  • 作用:简洁的语法生成一个数据结构:列表、字典、集合等
  • 注解:推导式属于Python独有的语法,目的是为了让代码更简洁,如果觉得不想用过完全可以不用。

    列表推导式

    参考 https://docs.python.org/zh-cn/3.9/tutorial/datastructures.html#list-comprehensions

    列表推导式创建列表的方式更简洁。常见的用法为,对序列或可迭代对象中的每个元素应用某种操作,用生成的结果创建新的列表;或用满足特定条件的元素创建子序列。

    普通列表推导式

    例如,创建平方值的列表:

    1. >> squares = []
    2. >> for x in range(10):
    3. ... squares.append(x**2)
    4. ...
    5. >> squares
    6. [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

    注意,循环结束后,创建(或重写)的名为 x 的变量仍然存在。

    1. >> x
    2. 9

    等价于:

    1. squares = [x**2 for x in range(10)]

    注意,循环结束后,创建(或重写)的名为 x 的变量不存在。

    1. >> x
    2. NameError: name 'x' is not defined

    列表推导式的方括号内包含以下内容:一个表达式,后面跟一个 for 子句,然后,是零个或多个 forif 子句。结果是新的列表,由对表达式依据后面的 forif 子句的内容进行求值计算而得出。 举例来说,以下列表推导式将两个列表中不相等的元素组合起来:

  1. >>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
  2. [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

等价于:

  1. >>> combs = []
  2. >>> for x in [1,2,3]:
  3. ... for y in [3,1,4]:
  4. ... if x != y:
  5. ... combs.append((x, y))
  6. ...
  7. >>> combs
  8. [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
  1. # [i*2+10 for i in range(10) if i%3==0]
  2. # 等效于
  3. l = []
  4. for i in range(10):
  5. if i % 3 == 0:
  6. l.append(i * 2 + 10)
  1. In[1]: [i * 2 + 10 for i in range(10) if i % 3 == 0]
  2. Out[1]: [10, 16, 22, 28]
  3. In [2]: [i*2 if i%3==0 else i for i in range(10) ]
  4. Out[2]: [0, 1, 2, 6, 4, 5, 12, 7, 8, 18]
  5. In[3]: [i for i in range(5) if i % 2 == 0]
  6. Out[3]: [0, 2, 4]
  7. In[4]: [i for i in range(5) if i % 2 == 0 and not i == 2]
  8. Out[4]: [0, 4]

以上是常见的用法,更多举例详见官网参考

嵌套的列表推导式

参考 https://docs.python.org/zh-cn/3.9/tutorial/datastructures.html#nested-list-comprehensions

  1. >>> matrix = [
  2. ... [1, 2, 3, 4],
  3. ... [5, 6, 7, 8],
  4. ... [9, 10, 11, 12],
  5. ... ]

下面的列表推导式可以转置行列:

  1. >>> [[row[i] for row in matrix] for i in range(4)]
  2. [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

如上节所示,嵌套的列表推导式是基于跟随其后的 for 进行求值的,所以这个例子等价于:

  1. >>> transposed = []
  2. >>> for i in range(4):
  3. ... transposed.append([row[i] for row in matrix])
  4. ...
  5. >>> transposed
  6. [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

反过来说,也等价于:

  1. >>> transposed = []
  2. >>> for i in range(4):
  3. ... # 下面3行实现了嵌套的list
  4. ... transposed_row = []
  5. ... for row in matrix:
  6. ... transposed_row.append(row[i])
  7. ... transposed.append(transposed_row)
  8. ...
  9. >>> transposed
  10. [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

集合推导式

返回一个集合

  1. In [1]: s={i*2+10 for i in range(10) if i%3==0}
  2. In [2]: type(s)
  3. Out[2]: set
  4. In [3]: s
  5. Out[3]: {10, 16, 22, 28}

【字典推导】

返回一个字典

  1. In [4]: dict={i:i*2+10 for i in range(10) if i%3==0}
  2. In [5]: type(dict)
  3. Out[5]: dict
  4. In [6]: dict
  5. Out[6]: {0: 10, 3: 16, 6: 22, 9: 28}

【生成器推导式】

参考 https://docs.python.org/zh-cn/3.9/tutorial/classes.html#generator-expressions
作用:列表生成器如果数据过大,会造成内存压力,此时可用生成器推导式来处理

  1. In [45]: a=(i*2+10 for i in range(10) if i%3==0)
  2. In [46]: a
  3. Out[46]: <generator object <genexpr> at 0x000000000445CC60>
  4. In [47]: type(a)
  5. Out[47]: generator
  6. In [48]: a.next()
  7. Out[48]: 10
  8. In [49]: a.next()
  9. Out[49]: 16
  10. In [50]: a.next()
  11. Out[50]: 22
  12. In [51]: a.next()
  13. Out[51]: 28

总结

一些更复杂的用法,可自行组合