Comme nous le savons tous, il existe une compréhension de liste, comme
[i for i in [1, 2, 3, 4]]
et il y a une compréhension du dictionnaire, comme
{i:j for i, j in {1: 'a', 2: 'b'}.items()}
mais
(i for i in (1, 2, 3))
aboutira à un générateur, pas à une compréhension Tuple
. Pourquoi donc?
À mon avis, une Tuple
est immuable, mais cela ne semble pas être la solution.
Vous pouvez utiliser une expression génératrice:
Tuple(i for i in (1, 2, 3))
mais les parenthèses étaient déjà prises pour… les expressions du générateur.
Raymond Hettinger (l'un des Python développeurs principaux) avait ceci à dire à propos des n-uplets dans un Tweet récent :
#python tip: En général, les listes sont pour boucler; tuples pour structs. Les listes sont homogènes; tuples hétérogène.Listes pour longueur variable.
Cela (à mon avis) confirme l'idée que si les éléments d'une séquence sont suffisamment liés pour être générés par un générateur, eh bien, il devrait s'agir d'une liste. Bien qu'un tuple soit itératif et ressemble simplement à une liste immuable, il s'agit en réalité de l'équivalent Python d'une structure C:
struct {
int a;
char b;
float c;
} foo;
struct foo x = { 3, 'g', 5.9 };
devient en Python
x = (3, 'g', 5.9)
Depuis Python 3.5 , vous pouvez également utiliser la syntaxe de décompression *
de splat pour décompresser une expression de générateur:
*(x for x in range(10)),
La compréhension fonctionne en boucle ou en itérant sur des éléments et en les affectant dans un conteneur, un tuple ne pouvant pas recevoir d’assignations.
Une fois qu'un tuple est créé, il ne peut être ni ajouté, ni étendu, ni attribué. La seule façon de modifier un tuple est si l'un de ses objets peut lui-même être assigné (c'est un conteneur non-tuple). Parce que le Tuple ne contient qu'une référence à ce type d'objet.
De plus, un tuple a son propre constructeur Tuple()
que vous pouvez donner à n'importe quel itérateur. Ce qui signifie que pour créer un tuple, vous pouvez faire:
Tuple(i for i in (1,2,3))
Comme l'a mentionné une autre affiche macm
, le moyen le plus rapide de créer un tuple à partir d'un générateur est Tuple([generator])
.
Compréhension de la liste:
$ python3 -m timeit "a = [i for i in range(1000)]"
10000 loops, best of 3: 27.4 usec per loop
Tuple de la compréhension de la liste:
$ python3 -m timeit "a = Tuple([i for i in range(1000)])"
10000 loops, best of 3: 30.2 usec per loop
Tuple du générateur:
$ python3 -m timeit "a = Tuple(i for i in range(1000))"
10000 loops, best of 3: 50.4 usec per loop
Tuple de déballage:
$ python3 -m timeit "a = *(i for i in range(1000)),"
10000 loops, best of 3: 52.7 usec per loop
Ma version de python:
$ python3 --version
Python 3.6.3
Vous devez donc toujours créer un tuple à partir d’une liste de compréhension, sauf si les performances ne sont pas un problème.
Ma meilleure hypothèse est qu'ils sont à court de crochets et ne pensent pas qu'il serait assez utile de justifier l'ajout d'une syntaxe "laide" ...
Les tuples ne peuvent pas être ajoutés efficacement comme une liste.
Ainsi, une compréhension de Tuple devrait utiliser une liste en interne puis être convertie en Tuple.
Ce serait la même chose que ce que vous faites maintenant: Tuple ([compréhension])
Les parenthèses ne créent pas un tuple. aka un = (deux) n'est pas un tuple. Le seul moyen de contourner est un = (deux) ou un = Tuple (deux). Donc, une solution est:
Tuple(i for i in myothertupleorlistordict)