En fait, les list comprehensions (ou dict…, ou tuple…, ou set…, maintenant, en py3) ne sont qu’un raccourcis de generator expressions…
est équivalent à…
list(a for a in range(10))
Et on peut donc les utiliser également pour générer un dict, par exemple:
{k: v for k, v in (('a', 1), ('b', 2), ('c', 3))}
Les exemples donnés ci-dessus n’ont évidemment pas grand intérêt, mais cette construction permet des conversions ou sélections d’iterables quelconques, relativement complexes, en une seule ligne. Leur expression abstraite est*:
expression(el1[, el2,
]) for el1[, el2,
] in iterable [if condition1 [if condition2
]]
expression peut être toute expression python, appel d’une fonction, définition d’une liste/tuple/…, opérateurs comme l’addition/multiplication/etc.
for el1[, el2, …] in iterable est exactement la même chose qu’une boucle for classique*!
[if condition1 [if condition2 …]] sont un ou plusieurs tests – si l’un d’entre eux renvoie False, le ou les éléments en cours sont ignorés, et on passe direct aux suivants.
En forme développée, cela donne, pour une liste comprehension*:
1 2 3 4 5 6 7 8
| lst = []
for el1[, el2,
] in iterable:
[if condition1:
continue
[if condition2:
continue
]]
lst.append(expression(el1[, el2,
])) |
De façon plus générale, une generator expression peut se “développer” comme cela:
function(expression(el1[, el2,
]) for el1[, el2,
] in iterable [if condition1 [if condition2
]])
1 2 3 4 5 6 7 8 9
| def gen(iterable):
for el1[, el2,
] in iterable:
[if condition1:
continue
[if condition2:
continue
]]
yield expression(el1[, el2,
]))
function(gen(iterable)) |
Je ne sais pas si c’est suffisamment clair… De toute façon, il en est de ces expressions comme des regex et de beaucoup d’autre chose – la meilleure façon de les comprendre, c’est de les utiliser (en commençant par des cas simples, évidemment).
Partager