6.2.4. 列表、集合与字典的显示
为了构建列表、集合或字典,Python 提供了名为“显示”的特殊句法,每个类型各有两种形式:
第一种是显式地列出容器内容
第二种是通过一组循环和筛选指令计算出来,称为 推导式。
推导式的常用句法元素为:
- comprehension ::=
assignment_expression
comp_for
- comp_for ::= ["async"] "for"
target_list
"in"or_test
[comp_iter
]- comp_iter ::=
comp_for
|comp_if
- comp_if ::= "if"
expression_nocond
[comp_iter
]
推导式的结构是一个单独表达式后面加至少一个 for
子句以及零个或更多个 for
或 if
子句。 在这种情况下,新容器的元素产生方式是将每个 for
或 if
子句视为一个代码块,按从左至右的顺序嵌套,然后每次到达最内层代码块时就对表达式进行求值以产生一个元素。
不过,除了最左边 for
子句中的可迭代表达式,推导式是在另一个隐式嵌套的作用域内执行的。 这能确保赋给目标列表的名称不会“泄露”到外层的作用域。
最左边的 for
子句中的可迭代对象表达式会直接在外层作用域中被求值,然后作为一个参数被传给隐式嵌套的作用域。 后续的 for
子句以及最左侧 for
子句中的任何筛选条件不能在外层作用域中被求值,因为它们可能依赖于从最左侧可迭代对象中获得的值。 例如: [x*y for x in range(10) for y in range(x, x+10)]
。
为了确保推导式得出的结果总是一个类型正确的容器,在隐式嵌套作用域内禁止使用 yield
和 yield from
表达式。
从 Python 3.6 开始,在 async def
函数中可以使用 async for
子句来迭代 asynchronous iterator。 在 async def
函数中构建推导式可以通过在打头的表达式后加上 for
或 async for
子句,也可能包含额外的 for
或 async for
子句,还可能使用 await
表达式。 如果一个推导式包含 async for
子句或者 await
表达式,则被称为 异步推导式。 异步推导式可以暂停执行它所在的协程函数。 另请参阅 PEP 530。
3.6 新版功能: 引入了异步推导式。
在 3.8 版更改: yield
和 yield from
在隐式嵌套的作用域中已被禁用。