为什么在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)