列表推导式

列表推导式（list comprehension），是程序设计语言的一类语法结构，用于基于描述创建一个列表（list）数据结构。相当于数学上的集合建构式符号。但不同于map与filter函数。
“list comprehension”没有统一的中文译法。有译作列表解析式、列表生成式、列表构建、列表理解等。
概述.
考虑下述集合建构式符号：
可读作：“formula_2是所有“formula_3乘formula_4”的数的集合，满足formula_4是自然数formula_6，并且formula_4的平方大于formula_8。”
列表推导式，与从一个输入列表或迭代器，依次生成一个列表的表示，有相同的语法构件：
在Haskell的列表推导式语法中，上述集合建造结构类似的写为如下：
s = [ 2*x | x &lt;- [0..], x^2 &gt; 3 ]
这里的列表codice_1表示formula_6，codice_2表示谓词，而codice_3表示输出表达式。列表推导式，按一个确定次序，给出结果（不同于集合的成员）；并且列表推导式，可以依次生成一个列表的成员，而非生成这个列表的全体，从而允许前面的对一个无穷列表的成员的Haskell定义。
历史.
在术语“列表推导式”使用之前，就存在了有关的构造。集合论编程语言SETL（1969年），有类似列表推导式的一种形成构造。比如，这个代码打印从codice_4到codice_5的所有素数：
计算机代数系统（1973年），有处理串流的类似构造。
首次对这种构造的使用术语“推导式”，是在1977年以后，和John Darlington，用在他们的函数式编程语言NPL的描述之中。在的回忆录《函数式编程语言的一些历史》中，他回想起：
在给术语“列表推导式”附加的脚注中，Turner还记述了：
Burstall和Darlington关于NPL的工作，在1980年代影响了很多函数式编程语言，但并非全部都包括了列表推导式。其中最有影响的，是1985年发行的，Turner的惰性纯函数式编程语言Miranda。后来开发的标准惰性纯函数式语言Haskell，包含了Miranda的很多特征，包括列表推导式。
Python示例.
Python语言的列表推导式和生成器表达式的语法示例：
»&gt; s = [2*x for x in range(10) if x**2 &gt; 3]
»&gt; print(s)
[4, 6, 8, 10, 12, 14, 16, 18]
»&gt; from itertools import count, islice
»&gt; s = (2*x for x in count(0) if x**2 &gt; 3)
»&gt; t = islice(s, 10)
»&gt; print([*t])
[4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
»&gt; print([*t])
»&gt; t = islice(s,10)
»&gt; print([*t])
[24, 26, 28, 30, 32, 34, 36, 38, 40, 42]
推广.
并行列表推导式.
格拉斯哥Haskell编译器，拥有一个扩展叫作“并行列表推导式”（也叫做拉链推导式），它允许在列表推导式语法中，有多个独立分支的限定符codice_6。用逗号codice_7分隔的限定符，是依赖的（“嵌套的”）；而用管道符号codice_8分隔的限定符，是并行求值的（这不涉及任何形式的多线程性，这只意味着这些分支是被合并的）。
-- 常规列表推导式
a = [(x,y) | x &lt;- [1..5], y &lt;- [6..8]]
-- [(1,6),(1,7),(1,8),(2,6),(2,7),(2,8),(3,6),(3,7),(3,8),(4,6),(4,7),(4,8),(5,6),(5,7),(5,8)]
-- 拉链列表推导式
b = [(x,y) | (x,y) &lt;- zip [1..5] [6..8]]
-- [(1,6),(2,7),(3,6)]
-- 并行列表推导式
c = [(x,y) | x &lt;- [1..5] | y &lt;- [6..8]]
-- [(1,6),(2,7),(3,8)]
Python语言的语法示例： 
»&gt; [(x, y) for x in range(1, 6) for y in range(6, 9)]
[(1, 6), (1, 7), (1, 8), (2, 6), (2, 7), (2, 8), (3, 6), (3, 7), (3, 8), (4, 6), (4, 7), (4, 8), (5, 6), (5, 7), (5, 8)]
»&gt; s = zip(range(1, 6), range(6, 9))
»&gt; t = [x for x in s]
»&gt; print(t)
[(1, 6), (2, 7), (3, 8)]
»&gt; from operator import add
»&gt; [*map(add, range(1, 6), range(6, 9))] # 有二个实际参数列表的map相当于Haskell的zipWith
[7, 9, 11]
»&gt; from itertools import starmap, zip_longest
»&gt; [*starmap(add, t)]
[7, 9, 11]
»&gt; s = zip_longest(range(1, 6), range(6, 9))
»&gt; t = [*s]
»&gt; print(t)
[(1, 6), (2, 7), (3, 8), (4, None), (5, None)]
»&gt; [*zip(*t)]
[(1, 2, 3, 4, 5), (6, 7, 8, None, None)]
单子推导式.
在Haskell中，单子推导式将列表推导式，推广为适用于任何单子。
集合推导式.
Python语言用于生成集合的语法示例：
»&gt; print(s)
字典推导式.
Python语言用于生成字典（关联数组）的语法示例： 
»&gt; print(s)
类似构造.
C++.
C++没有直接支持列表推导的任何语言特性，但运算符重载（例如，重载|，»，» =）已成功用于为“嵌入式”查询领域特定语言提供表达式语法。 或者，可以使用erase–remove惯用法来构造列表推导以选择容器中的元素，并使用STL算法for_each来转换它们。
using namespace std;
template&lt;class C, class P, class T&gt;
C comprehend(C&amp;&amp; source, const P&amp; predicate, const T&amp; transformation)
 // 初始化目标
 C d = forward&lt;C&gt;(source);
 // 元素过滤
 d.erase(remove_if(begin(d), end(d), predicate), end(d));
 // 应用变换
 for_each(begin(d), end(d), transformation);
 return d;
int main()
 list&lt;int&gt; range(10); 
 // range 是一个有10个元素的list, 全是0
 iota(begin(range), end(range), 1);
 // range 现在包含 1,2...,10
 list&lt;int&gt; result = comprehend(
 range,
 [](int x){return x*x &lt;= 3;},
 [](int &amp;x){x *= 2;});
 // 结果现在包含 4,6...,20