una - ¿Por qué no hay comprensión de la tupla en Python?
llenar una lista en python (10)
Como todos sabemos, hay una lista de comprensión, como
[i for i in [1, 2, 3, 4]]
y hay diccionario de comprensión, como
{i:j for i, j in {1: ''a'', 2: ''b''}.items()}
pero
(i for i in (1, 2, 3))
Terminará en un generador, no en una tuple
comprensión. ¿Porqué es eso?
Mi conjetura es que una tuple
es inmutable, pero esta no parece ser la respuesta.
Como mencionó otro póster de macm
, la forma más rápida de crear una tupla a partir de un generador es la tuple([generator])
.
Comparación de rendimiento
Lista de comprensión:
$ python3 -m timeit "a = [i for i in range(1000)]" 10000 loops, best of 3: 27.4 usec per loop
Tuple de la lista de comprensión:
$ python3 -m timeit "a = tuple([i for i in range(1000)])" 10000 loops, best of 3: 30.2 usec per loop
Tuple del generador:
$ python3 -m timeit "a = tuple(i for i in range(1000))" 10000 loops, best of 3: 50.4 usec per loop
Tuple de desembalaje:
$ python3 -m timeit "a = *(i for i in range(1000))," 10000 loops, best of 3: 52.7 usec per loop
Mi versión de python :
$ python3 --version
Python 3.6.3
Por lo tanto, siempre debe crear una tupla a partir de una lista de comprensión, a menos que el rendimiento no sea un problema.
Creo que es simplemente por claridad, no queremos saturar el lenguaje con demasiados símbolos diferentes. Además, una comprensión de la tuple
nunca es necesaria , una lista solo se puede usar en su lugar con diferencias de velocidad despreciables, a diferencia de una comprensión de dictado en lugar de una comprensión de lista.
La comprensión funciona en bucle o iteración sobre los elementos y asignándolos a un contenedor, un Tuple no puede recibir asignaciones.
Una vez que se crea un Tuple, no se puede agregar, extender o asignar. La única forma de modificar una tupla es si uno de sus objetos puede asignarse (no es un contenedor de tuplas). Porque el Tuple solo tiene una referencia a ese tipo de objeto.
Además, una tupla tiene su propio constructor tuple()
que puede proporcionar a cualquier iterador. Lo que significa que para crear una tupla, podrías hacer:
tuple(i for i in (1,2,3))
Las tuplas no pueden ser anexadas eficientemente como una lista.
Por lo tanto, una comprensión de la tupla tendría que usar una lista internamente y luego convertirla en una tupla.
Eso sería lo que haces ahora: tuple ([comprensión])
Los paréntesis no crean una tupla. aka uno = (dos) no es una tupla. La única forma de evitarlo es uno = (dos) o uno = tupla (dos). Así que una solución es:
tuple(i for i in myothertupleorlistordict)
Mi mejor conjetura es que se quedaron sin corchetes y no pensaron que sería lo suficientemente útil como para justificar agregar una sintaxis "fea" ...
Podemos generar tuplas a partir de una lista de comprensión. El siguiente agrega dos números secuencialmente en una tupla y da una lista de los números 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)]
Puedes usar una expresión generadora:
tuple(i for i in (1, 2, 3))
pero ya se tomaron paréntesis para ... expresiones del generador.
Raymond Hettinger (uno de los desarrolladores principales de Python) dijo esto sobre las tuplas en un tweet reciente :
#python tip: Generalmente, las listas son para bucles; Tuplas para estructuras. Las listas son homogéneas; Tuplas heterogéneas.Listas de longitud variable.
Esto (para mí) apoya la idea de que si los elementos en una secuencia están lo suficientemente relacionados como para ser generados por un generador, bueno, entonces debería ser una lista. Aunque una tupla es iterable y parece simplemente una lista inmutable, en realidad es el equivalente de Python de una estructura C:
struct {
int a;
char b;
float c;
} foo;
struct foo x = { 3, ''g'', 5.9 };
se convierte en Python
x = (3, ''g'', 5.9)
Desde Python 3.5 , también puede usar la sintaxis de desempaquetado de splat *
para desempaquetar una expresión del generador:
*(x for x in range(10)),