2.30. Compréhensions#

Une compréhension construit une nouvelle liste, un nouvel ensemble, un nouveau dictionnaire ou un nouveau générateur à partir d’un itérable existant, en une seule expression. C’est un remplacement du schéma courant consistant à partir d’un conteneur vide et à y ajouter des éléments dans une boucle.

2.30.1. Compréhensions de liste#

squares = [x * x for x in range(5)]
print(squares)

Sortie

[0, 1, 4, 9, 16]

La même boucle écrite explicitement :

squares = []
for x in range(5):
    squares.append(x * x)

La forme par compréhension est une expression unique qui construit la liste directement. Il n’y a pas de squares = [] ni de .append – le résultat est la valeur de la compréhension.

The expression "[f(x) for x in xs if cond]" annotated: the leading expression is the result, the for clause names the loop variable, the if clause filters which items are kept.

L’expression de tête produit chaque élément ; la clause for nomme la variable de boucle ; une clause if facultative filtre les éléments.#

2.30.2. Filtrer avec if#

Une clause if facultative ne conserve que les éléments correspondants :

evens = [x for x in range(10) if x % 2 == 0]
print(evens)

Sortie

[0, 2, 4, 6, 8]

Le filtre s’exécute avant l’expression de tête – x % 2 == 0 est vérifié en premier ; seules les valeurs correspondantes atteignent x pour la sortie.

2.30.3. Compréhensions de dictionnaire et d’ensemble#

La même forme fonctionne avec les littéraux de dictionnaire et d’ensemble.

Une compréhension de dictionnaire comporte une paire key: value avant le for :

squares = {x: x * x for x in range(5)}
print(squares)

Sortie

{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

Une compréhension d’ensemble utilise des accolades et une expression unique :

unique_lengths = {len(w) for w in ["a", "bb", "c", "bb"]}
print(unique_lengths)

Sortie

{1, 2}

2.30.4. Expressions génératrices#

Les parenthèses produisent une expression génératrice au lieu d’une liste. Les valeurs sont calculées une à une, à la demande :

total = sum(x * x for x in range(1000))

Aucune liste d’un million d’éléments n’est jamais construite. Les valeurs s’écoulent une par une vers sum(), qui les additionne et écarte chacune au fur et à mesure.

Les expressions génératrices sont le bon choix pour alimenter des valeurs dans une fonction de réduction (sum(), max(), any(), all()) ou tout autre code consommant un itérateur – elles économisent la mémoire qu’aurait utilisée la liste équivalente.

2.30.5. Quand ne pas utiliser de compréhension#

Les compréhensions sont concises mais pas toujours plus claires. Optez pour une simple boucle for quand :

  • Le corps a besoin de plus d’une instruction (une compréhension n’accepte qu’une seule expression).

  • Le corps a des effets de bord (afficher, écrire dans un fichier) – les compréhensions servent à construire une collection, pas à exécuter des actions.

  • Le filtre ou la transformation comporte tant de parties que la compréhension ne se lit plus de gauche à droite.