IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Python, de zéro


précédentsommairesuivant

XIII. Les listes en intension

La notion de « liste en intension » (appelée aussi parfois « liste en compréhension ») exprime une forme d’écriture permettant de générer de nouvelles listes directement par traitement de listes existantes. Le terme « liste » doit être pris ici au sens large (englobant donc aussi les tuples, les ensembles et les dictionnaires et de façon plus générale tout ce qui est itérable).

Le terme « intension » (à ne pas confondre avec « intention ») se traduit par « conception par définition » et s’oppose à « extension » (qui se traduit, lui, par « conception par l’exemple »).

La syntaxe générale est de remplacer les éléments situés entre les crochets par une instruction de création faisant appel à une liste déjà existante.

Exemple : partons d'une liste de base contenant les entiers de 0 à 9…

 
Sélectionnez
1.
2.
3.
>>> tab=list(range(10))
>>> tab
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Demandons ensuite à créer une seconde liste issue de la première, mais ne contenant que les éléments pairs.

De ce qu’on a vu jusqu’à présent, la méthode habituelle serait d’amorcer une seconde liste vide et la remplir à partir de la première en évaluant chaque élément un à un…

 
Sélectionnez
1.
2.
3.
4.
5.
6.
>>> pair=[]
>>> for x in tab:
...    if (x%2) == 0: pair.append(x)
...
>>> pair
[0, 2, 4, 6, 8]

Python offre toutefois pour ce faire une syntaxe plus concise permettant de créer directement la seconde liste à partir des éléments de la première, éléments traités alors directement dans l’instruction de création.

 
Sélectionnez
1.
2.
3.
>>> pair=[x for x in tab if (x%2) == 0]
>>> pair
[0, 2, 4, 6, 8]

De là, on peut continuer en demandant par exemple à créer une troisième liste, toujours issue de la première, mais ne contenant cette fois que les éléments impairs et mis au carré…

 
Sélectionnez
1.
2.
3.
>>> carre_impair=[x**2 for x in tab if (x%2) != 0]
>>> carre_impair
[1, 9, 25, 49, 81]

Cette écriture, qui permet de créer des listes avec une grande concision, tend à se rapprocher de la notation utilisée en mathématiques dans la théorie des ensembles.

  • Écriture mathématique : carre_pair={x²|x ∈ tab, [x]2 = 0}
  • Écriture python : carre_pair=[x**2 for x in tab if (x%2) == 0]

Le principe général est d’inclure la boucle dans la création de la seconde liste en y rajoutant ensuite les évaluations et traitements éventuels.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
# Algorithme classique
>>> res=[]
>>> for x in orig:
...    if test(x) == v:
...        res.append(fct(x))
...
 
Sélectionnez
1.
2.
# Algorithme en compréhension
>>> res=[fct(x) for x in orig if test(x) == v]

L’un des avantages de cette écriture est qu’elle supprime l’utilisation du list.append() qui peut être très gourmand en ressources.

Elle fonctionne à partir de tout itérable et peut générer tout aussi bien des listes que des tuples, des ensembles ou des dictionnaires.

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
>>> tab=range(10)
>>> carre_pair=list(x**2 for x in tab if (x%2) == 0)
>>> carre_pair
[0, 4, 16, 36, 64]
>>>
>>> cube_impair=dict((str(x), x**3) for x in tab if (x%2) != 0)
>>> cube_impair
{'1': 1, '3': 27, '9': 729, '5': 125, '7': 343}
>>>
>>> domino=tuple((x, y) for x in range(7) for y in range(x+1))
>>> domino
((0, 0), (1, 0), (1, 1), (2, 0), (2, 1), (2, 2), (3, 0), (3, 1), (3, 2), (3, 3), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (5, 0), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (6, 0), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6))

À noter : la ou les variable(s) interne(s) utilisée(s) pour itérer la liste n’influe(nt) pas sur les variables externes même si des variables de même nom existent…

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
>>> x=1234
>>> tab=range(5)
>>> carre=tuple(x**2 for x in tab)
>>> carre
(0, 1, 4, 9, 16)
>>> x
1234

… inversement, les variables externes à l’expression sont accessibles dans l’expression si celle‑ci ne redéfinit pas des variables de même nom.

 
Sélectionnez
1.
2.
3.
4.
5.
>>> toto=500
>>> tab=range(5)
>>> carre=tuple((x**2, toto) for x in tab)
>>> carre
((0, 500), (1, 500), (4, 500), (9, 500), (16, 500))

En fait, la ou les variables internes utilisées pour itérer la liste sont créées à chaque itération et ceci de façon distincte d’une éventuelle variable externe portant le même nom :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
>>> x=1234
>>> id(x)
140237834012528
>>> tab=range(5)
>>> carre=tuple((id(x), x**2) for x in tab)
>>> carre
((10771488, 0), (10771520, 1), (10771552, 4), (10771584, 9), (10771616, 16))
>>> id(x)
140237834012528

précédentsommairesuivant

Copyright © 2022 Svear (svear@free.fr) Permission est accordée de copier, distribuer ou modifier ce document selon les termes de la « Licence de Documentation Libre GNU » (GNU Free Documentation License), version 1.1 ou toute version ultérieure publiée par la Free Software Foundation.