Why is there no tuple comprehension in Python?
You can use a generator expression:
tuple(i for i in (1, 2, 3))
but parentheses were already taken for … generator expressions.
Raymond Hettinger (one of the Python core developers) had this to say about tuples in a recent tweet:
#python tip: Generally, lists are for looping; tuples for structs. Lists are homogeneous; tuples heterogeneous. Lists for variable length.
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:
struct {
int a;
char b;
float c;
} foo;
struct foo x = { 3, 'g', 5.9 };
becomes in Python
x = (3, 'g', 5.9)
Since Python 3.5, you can also use splat *
unpacking syntax to unpack a generator expresion:
*(x for x in range(10)),
As another poster macm
mentioned, the fastest way to create a tuple from a generator is 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 loop
-
Tuple from list comprehension:
$ python3 -m timeit "a = tuple([i for i in range(1000)])" 10000 loops, best of 3: 30.2 usec per loop
-
Tuple from generator:
$ python3 -m timeit "a = tuple(i for i in range(1000))" 10000 loops, best of 3: 50.4 usec per loop
-
Tuple from unpacking:
$ python3 -m timeit "a = *(i for i in range(1000))," 10000 loops, best of 3: 52.7 usec per loop
My version of python:
$ python3 --version
Python 3.6.3
So you should always create a tuple from a list comprehension unless performance is not an issue.