为什么 Python 中没有元组理解?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16940293/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is there no tuple comprehension in Python?
提问by Shady Xu
As we all know, there's list comprehension, like
众所周知,有列表理解,比如
[i for i in [1, 2, 3, 4]]
and there is dictionary comprehension, like
还有字典理解,比如
{i:j for i, j in {1: 'a', 2: 'b'}.items()}
but
但
(i for i in (1, 2, 3))
will end up in a generator, not a tuplecomprehension. Why is that?
最终会出现在生成器中,而不是tuple理解中。这是为什么?
My guess is that a tupleis immutable, but this does not seem to be the answer.
我的猜测是 atuple是不可变的,但这似乎不是答案。
采纳答案by Martijn Pieters
You can use a generator expression:
您可以使用生成器表达式:
tuple(i for i in (1, 2, 3))
but parentheses were already taken for … generator expressions.
但是括号已经被用于……生成器表达式。
回答by mgilson
My best guess is that they ran out of brackets and didn't think it would be useful enough to warrent adding an "ugly" syntax ...
我最好的猜测是他们用完了括号,并且认为它不足以警告添加“丑陋”的语法......
回答by jamylak
I believe it's simply for the sake of clarity, we do not want to clutter the language with too many different symbols. Also a tuplecomprehension is never necessary, a list can just be used instead with negligible speed differences, unlike a dict comprehension as opposed to a list comprehension.
我相信这只是为了清楚起见,我们不想用太多不同的符号来混淆语言。此外,tuple理解永远不是必需的,可以使用列表来代替,速度差异可以忽略不计,这与字典理解而不是列表理解不同。
回答by Inbar Rose
Comprehension works by looping or iterating over items and assigning them into a container, a Tuple is unable to receive assignments.
理解通过循环或迭代项目并将它们分配到容器中来工作,元组无法接收分配。
Once a Tuple is created, it can not be appended to, extended, or assigned to. The only way to modify a Tuple is if one of its objects can itself be assigned to (is a non-tuple container). Because the Tuple is only holding a reference to that kind of object.
元组一旦创建,就不能附加、扩展或分配给它。修改元组的唯一方法是它的一个对象本身是否可以分配给(是非元组容器)。因为元组只持有对那种对象的引用。
Also - a tuple has its own constructor tuple()which you can give any iterator. Which means that to create a tuple, you could do:
此外 - 元组有自己的构造函数tuple(),您可以为其提供任何迭代器。这意味着要创建一个元组,您可以执行以下操作:
tuple(i for i in (1,2,3))
回答by chepner
Raymond Hettinger (one of the Python core developers) had this to say about tuples in a recent tweet:
Raymond Hettinger(Python 核心开发人员之一)在最近的一条推文中谈到了元组:
#python tip: Generally, lists are for looping; tuples for structs. Lists are homogeneous; tuples heterogeneous. Lists for variable length.
#python 提示:通常,列表用于循环;结构元组。列表是同质的;元组异构。可变长度的列表。
This (to me) supports the idea that if the items in a sequence are related enough to be generated by a, well, generator, then it should be a list. Although a tuple is iterable and seems like simply a immutable list, it's really the Python equivalent of a C struct:
这(对我而言)支持这样一种想法,即如果序列中的项目足够相关,可以由生成器生成,那么它应该是一个列表。尽管元组是可迭代的并且看起来只是一个不可变的列表,但它实际上是 C 结构体的 Python 等价物:
struct {
int a;
char b;
float c;
} foo;
struct foo x = { 3, 'g', 5.9 };
becomes in Python
在 Python 中变成
x = (3, 'g', 5.9)
回答by macm
Tuples cannot efficiently be appended like a list.
元组不能像列表一样有效地附加。
So a tuple comprehension would need to use a list internally and then convert to a tuple.
所以元组理解需要在内部使用一个列表,然后转换为一个元组。
That would be the same as what you do now : tuple( [ comprehension ] )
这将与您现在所做的相同: tuple( [理解] )
回答by Rohit Malgaonkar
We can generate tuples from a list comprehension. The following one adds two numbers sequentially into a tuple and gives a list from numbers 0-9.
我们可以从列表推导式中生成元组。下面的代码将两个数字按顺序添加到一个元组中,并给出一个数字 0-9 的列表。
>>> print 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)]
回答by ilias iliadis
Parentheses do not create a tuple. aka one = (two) is not a tuple. The only way around is either one = (two,) or one = tuple(two). So a solution is:
括号不会创建元组。aka one = (two) 不是元组。唯一的解决方法是 one = (two,) 或 one = tuple(two)。所以一个解决方案是:
tuple(i for i in myothertupleorlistordict)
回答by czheo
Since Python 3.5, you can also use splat *unpacking syntax to unpack a generator expresion:
从 Python 3.5 开始,您还可以使用 splat*解包语法来解包生成器表达式:
*(x for x in range(10)),
回答by Tom
As another poster macmmentioned, the fastest way to create a tuple from a generator is tuple([generator]).
正如另一位海报所macm提到的,从生成器创建元组的最快方法是tuple([generator]).
Performance Comparison
性能比较
List comprehension:
$ python3 -m timeit "a = [i for i in range(1000)]" 10000 loops, best of 3: 27.4 usec per loopTuple from list comprehension:
$ python3 -m timeit "a = tuple([i for i in range(1000)])" 10000 loops, best of 3: 30.2 usec per loopTuple from generator:
$ python3 -m timeit "a = tuple(i for i in range(1000))" 10000 loops, best of 3: 50.4 usec per loopTuple from unpacking:
$ python3 -m timeit "a = *(i for i in range(1000))," 10000 loops, best of 3: 52.7 usec per loop
列表理解:
$ python3 -m timeit "a = [i for i in range(1000)]" 10000 loops, best of 3: 27.4 usec per loop来自列表理解的元组:
$ python3 -m timeit "a = tuple([i for i in range(1000)])" 10000 loops, best of 3: 30.2 usec per loop来自生成器的元组:
$ python3 -m timeit "a = tuple(i for i in range(1000))" 10000 loops, best of 3: 50.4 usec per loop来自解包的元组:
$ python3 -m timeit "a = *(i for i in range(1000))," 10000 loops, best of 3: 52.7 usec per loop
My version of python:
我的python版本:
$ python3 --version
Python 3.6.3
So you should always create a tuple from a list comprehension unless performance is not an issue.
因此,除非性能不是问题,否则您应该始终从列表理解中创建元组。

