6.2.4. 列表、集合与字典的显示

为了构建列表、集合或字典,Python 提供了名为“显示”的特殊句法,每个类型各有两种形式:

  • 第一种是显式地列出容器内容

  • 第二种是通过一组循环和筛选指令计算出来,称为 推导式

推导式的常用句法元素为:

  1. comprehension ::= assignment_expression comp_for
  2. comp_for ::= ["async"] "for" target_list "in" or_test [comp_iter]
  3. comp_iter ::= comp_for | comp_if
  4. comp_if ::= "if" expression_nocond [comp_iter]

推导式的结构是一个单独表达式后面加至少一个 for 子句以及零个或更多个 forif 子句。 在这种情况下,新容器的元素产生方式是将每个 forif 子句视为一个代码块,按从左至右的顺序嵌套,然后每次到达最内层代码块时就对表达式进行求值以产生一个元素。

不过,除了最左边 for 子句中的可迭代表达式,推导式是在另一个隐式嵌套的作用域内执行的。 这能确保赋给目标列表的名称不会“泄露”到外层的作用域。

最左边的 for 子句中的可迭代对象表达式会直接在外层作用域中被求值,然后作为一个参数被传给隐式嵌套的作用域。 后续的 for 子句以及最左侧 for 子句中的任何筛选条件不能在外层作用域中被求值,因为它们可能依赖于从最左侧可迭代对象中获得的值。 例如: [x*y for x in range(10) for y in range(x, x+10)]

为了确保推导式得出的结果总是一个类型正确的容器,在隐式嵌套作用域内禁止使用 yieldyield from 表达式。

从 Python 3.6 开始,在 async def 函数中可以使用 async for 子句来迭代 asynchronous iterator。 在 async def 函数中构建推导式可以通过在打头的表达式后加上 forasync for 子句,也可能包含额外的 forasync for 子句,还可能使用 await 表达式。 如果一个推导式包含 async for 子句或者 await 表达式,则被称为 异步推导式。 异步推导式可以暂停执行它所在的协程函数。 另请参阅 PEP 530

3.6 新版功能: 引入了异步推导式。

在 3.8 版更改: yieldyield from 在隐式嵌套的作用域中已被禁用。