为什么在Python中没有元组理解?

众所周知,列表理解就像

[i for i in [1, 2, 3, 4]] 

有字典理解,就像

 {i:j for i, j in {1: 'a', 2: 'b'}.items()} 

 (i for i in (1, 2, 3)) 

将最终在一个生成器,而不是一个tuple理解。 这是为什么?

我的猜测是一个tuple是不可变的,但这似乎不是答案。

你可以使用一个生成器expression式:

 tuple(i for i in (1, 2, 3)) 

但括号已经被用于生成器expression式。

Raymond Hettinger(Python核心开发人员之一)在最近的tweet中对这个元组进行了说明:

#python提示:通常,列表是循环的; 元组的结构。 列表是同质的; 元组异构。可变长度列表。

这个(对我来说)支持这样一个想法,即如果一个序列中的项目足够相关以便由一个生成器生成,那么它应该是一个列表。 尽pipe一个元组是可迭代的,看起来像一个不可变列表,但它实际上是C结构的Python等价物:

 struct { int a; char b; float c; } foo; struct foo x = { 3, 'g', 5.9 }; 

成为Python

 x = (3, 'g', 5.9) 

理解通过循环或遍历项目并将其分配到一个容器中起作用,元组无法接收分配。

一旦创build了一个元组,它就不能被附加到,扩展或分配给它。 修改元组的唯一方法是如果其中一个对象本身可以被赋值(是一个非元组容器)。 因为Tuple只持有对这种对象的引用。

另外 – 一个元组有它自己的构造函数tuple() ,你可以给任何迭代器。 这意味着要创build一个元组,你可以这样做:

 tuple(i for i in (1,2,3)) 

我最好的猜测是,他们没有使用括号,并且认为这不足以保证添加一个“丑陋”的语法。

我相信这只是为了清楚起见,我们不想用太多不同的符号来混淆语言。 另外, tuple理解从来就不是必须的 ,只能用一个列表而不用速度差异,而不是一个词典理解而不是列表理解。

元组不能像列表一样高效地追加。

所以元组理解需要在内部使用一个列表,然后转换成一个元组。

这和你现在所做的一样:元组([comprehension])

圆括号不会创build元组。 又名一个=(二)不是一个元组。 唯一的方法是一个=(两个)或一个=元组(两个)。 所以一个解决scheme是:

 tuple(i for i in myothertupleorlistordict) 

可以从列表理解中生成元组。 这一个将2个数字顺序地添加到一个元组中,并从数字0-9给出一个列表。

打印k [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 ,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48 ,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73 ,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98 ,99]

  >>> r= [tuple(k[i:i+2]) for i in xrange(10) if not i%2] >>> print r [(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)] 

当然,可以生成非常自然的数据集:所以“必须生成的理解”并不是针对元组理解的论点。 EGS:

(“a”,1,“b”,“2”,“c”,3)

(2,“prime”,3,“prime”,4,“nonprime”,5,prime,6,nonprime)