list、set、dict 等的生成式构造
(参看教程 5.1.3 节,语言手册 6.2.4、6.2.5、6.2.6、6.2.7 节)

在 Python 语言里,存在两种直接描述 list、set 和 dict 等 类型的对象的方式,第一种是前面介绍过,以一系列表达式的方式直接列出它们包含的元素。另一种方式就是这里要介绍的生成描述形式(内涵描述形式)。下面以 list 类型为例介绍生成式描述的语法和语义。

在英文手册和书籍里把这种描述称为表(元组,字典等)的 comprehension,意为其 "内涵表示形式"。内涵和外延的概念来自逻辑和集合论。用列举集合元素的方式定义集合是集合的外延表示形式;用说明集合元素的性质的方式定义集合,是集合的内涵表示形式。

编程语言里的 comprehension 和 "内涵描述" 还是有差别的,因为在这里需要 "可计算",实际上是设计了一套通用的描述方式,可以针对这种描述定义一个通用的计算过程,生成出相应集合的所有元素。下面把这种描述称为 "表生成式"(类似的,"元组生成式","字典生成式")。

生成式是一套描述方式,用于描述所需的 list 元素,使用生成式的 list 描述形式为

	[ 生成式 ]
方括号表示描述的是表,"生成式"描述表中元素,其最简单形式是:
	表达式 for 变量 in 迭代器
下面是一个简单实例:
	[(x * 3) // 5 for x in range(10)]
这个表达式生成的表是 [0, 0, 1, 1, 2, 3, 3, 4, 4, 5],注意这里是整除,得到的是整数。

在这个基本形式后面还可以跟着任意多个 for 片段(形式为 "for 变量 in 迭代器")或 if 片段(形式为 "if 条件",条件里可以引用前面出现的变量或描述这个集合时可见的变量)。

下面是一个例子:

	>>> x = 10
	>>> [x * y for y in range(10) if (x + y) % 3 != 0]
	[0, 10, 30, 40, 60, 70, 90]
这个表达式生成的表里的元素是由 x 和 y 的一系列取值相乘得到的结果,但去掉了那些 x 和 y 的和可以整除 3 的情况。

如果生成式里包括多个 for 片段,这些片段中的变量从左到右逐个从相应的迭代器里取值,在取得了一组值之后,就基于这些值计算 "表达式",得到这个表里的一个元素。

如果在其中出现了 if 片段,就利用其中的条件剔除不满足条件的取值组。显然,在一个 if 片段的条件里,只应涉及其左边的 for 片段引进的变量(还可以涉及这里可以看见的其他变量,如上例里的 x)。 集合和字典的生成式的形式与此类似。

下面是一个构造集合的例子:

	>>> x = 7
	>>> {x * y - z for y in range(4) for z in range(6) if x * y % 2 == 0}
	{0, 9, 10, 11, 12, 13, 14, -1, -5, -4, -3, -2}
完全可以写出多个 if 片段,对要生成的元素提出多种过滤条件。
本页及相关页面(除另声明者外)由裘宗燕创建维护,可自由用于各种学习活动。其他使用需得到作者许可。