Skip to content

Compréhensions de listes en Python

En Python, vous pouvez créer une nouvelle liste à l’aide des compréhensions de liste. C’est plus simple que d’utiliser la boucle for.

Cet article décrit le contenu suivant.

  • Bases de la compréhension des listes
  • Lister les compréhensions avec if
  • Lister les compréhensions avec des expressions conditionnelles (comme si sinon)
  • Lister les compréhensions avec zip(), enumerate()
  • Compréhensions de listes imbriquées
  • Définir les compréhensions
  • Compréhensions du dictionnaire
  • Générateur d’expressions

Consultez l’article suivant pour connaître les bases de l’instruction for.

Consultez l’article suivant pour obtenir des exemples d’utilisation des compréhensions de liste.

Bases de la compréhension des listes

Les compréhensions de liste s’écrivent comme suit :

[expression for variable_name in iterable]

Chaque élément de itérable, tel qu’une liste ou un tuple, est extrait en tant que variable_name et évalué avec expression. Une nouvelle liste est créée avec le résultat évalué par expression comme un élément.

Un exemple de compréhension de liste est montré avec un équivalent pour l’instruction.

squares = [i**2 for i in range(5)]
print(squares)
# [0, 1, 4, 9, 16]
squares = []
for i in range(5):
    squares.append(i**2)

print(squares)
# [0, 1, 4, 9, 16]

Bien que map() puisse faire la même chose, la compréhension de liste est préférée pour plus de simplicité et de clarté.

Lister les compréhensions avec if

Dans les compréhensions de liste, if peut être utilisé comme suit :

[expression for variable_name in iterable if condition]

Seuls les éléments de iterable qui sont True pour condition sont évalués avec expression. Les éléments de iterable qui sont False pour la condition ne sont pas inclus dans la liste des résultats.

odds = [i for i in range(10) if i % 2 == 1]
print(odds)
# [1, 3, 5, 7, 9]
odds = []
for i in range(10):
    if i % 2 == 1:
        odds.append(i)

print(odds)
# [1, 3, 5, 7, 9]

Bien que filter() puisse faire la même chose, la compréhension de liste est préférée pour plus de simplicité et de clarté.

Lister les compréhensions avec des expressions conditionnelles (comme si sinon)

Dans l’exemple ci-dessus, les éléments qui ne remplissent pas la condition sont exclus de la nouvelle liste.

Si vous souhaitez appliquer une autre opération aux éléments qui ne remplissent pas la condition comme if else, utilisez des expressions conditionnelles.

En Python, les expressions conditionnelles peuvent être écrites comme suit :

X est la valeur ou l’expression pour True et Y est la valeur ou l’expression pour False.

Vous pouvez l’utiliser pour la partie expression des compréhensions de liste :

odd_even = ['odd' if i % 2 == 1 else 'even' for i in range(10)]
print(odd_even)
# ['even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd']
odd_even = []
for i in range(10):
    if i % 2 == 1:
        odd_even.append('odd')
    else:
        odd_even.append('even')

print(odd_even)
# ['even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd']

Il est également possible d’appliquer différentes opérations à l’élément d’origine en fonction de la condition comme suit :

odd10 = [i * 10 if i % 2 == 1 else i for i in range(10)]
print(odd10)
# [0, 10, 2, 30, 4, 50, 6, 70, 8, 90]

Lister les compréhensions avec zip(), enumerate()

Dans l’instruction for, zip() et enumerate() sont souvent utilisés. zip() agrège les éléments de plusieurs itérables et enumerate() renvoie une valeur et son index.

Bien sûr, vous pouvez également utiliser zip() et enumerate() dans les compréhensions de liste.

Lister les compréhensions avec zip() :

l_str1 = ['a', 'b', 'c']
l_str2 = ['x', 'y', 'z']

l_zip = [(s1, s2) for s1, s2 in zip(l_str1, l_str2)]
print(l_zip)
# [('a', 'x'), ('b', 'y'), ('c', 'z')]
l_zip = []
for s1, s2 in zip(l_str1, l_str2):
    l_zip.append((s1, s2))

print(l_zip)
# [('a', 'x'), ('b', 'y'), ('c', 'z')]

Lister les compréhensions avec enumerate() :

l_enu = [(i, s) for i, s in enumerate(l_str1)]
print(l_enu)
# [(0, 'a'), (1, 'b'), (2, 'c')]
l_enu = []
for i, s in enumerate(l_str1):
    l_enu.append((i, s))

print(l_enu)
# [(0, 'a'), (1, 'b'), (2, 'c')]

Vous pouvez également utiliser si.

l_zip_if = [(s1, s2) for s1, s2 in zip(l_str1, l_str2) if s1 != 'b']
print(l_zip_if)
# [('a', 'x'), ('c', 'z')]

Il est également possible de calculer une nouvelle valeur à l’aide de chaque élément.

l_int1 = [1, 2, 3]
l_int2 = [10, 20, 30]

l_sub = [i2 - i1 for i1, i2 in zip(l_int1, l_int2)]
print(l_sub)
# [9, 18, 27]

Compréhensions de listes imbriquées

Les compréhensions de liste peuvent être imbriquées tout comme les boucles for sont imbriquées.

[expression for variable_name1 in iterable1
    for variable_name2 in iterable2
        for variable_name3 in iterable3 ... ]

Les sauts de ligne et l’indentation sont ajoutés pour plus de commodité, mais ils ne sont pas obligatoires.

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

flat = [x for row in matrix for x in row]
print(flat)
# [1, 2, 3, 4, 5, 6, 7, 8, 9]
flat = []
for row in matrix:
    for x in row:
        flat.append(x)

print(flat)
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

Un autre exemple:

cells = [(row, col) for row in range(3) for col in range(2)]
print(cells)
# [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)]

Vous pouvez également utiliser si.

cells = [(row, col) for row in range(3)
         for col in range(2) if col == row]
print(cells)
# [(0, 0), (1, 1)]
cells = [(row, col) for row in range(3) if row % 2 == 0
         for col in range(2) if col % 2 == 0]
print(cells)
# [(0, 0), (2, 0)]

Définir les compréhensions

Si vous remplacez les crochets [] dans la compréhension de la liste par des accolades {}, un ensemble (objet de type ensemble) est créé.

{expression for variable_name in iterable}
s = {i**2 for i in range(5)}

print(s)
# {0, 1, 4, 9, 16}

Pour plus d’informations sur l’ensemble, consultez l’article suivant.

Compréhensions du dictionnaire

Des dictionnaires (objets de type dict) peuvent également être créés avec des compréhensions de dictionnaire.

Utilisez {} et spécifiez la clé et la valeur dans la partie expression en tant que clé : valeur.

{key: value for variable_name in iterable}

N’importe quelle valeur ou expression peut être spécifiée pour la clé et la valeur.

l = ['Alice', 'Bob', 'Charlie']

d = {s: len(s) for s in l}
print(d)
# {'Alice': 5, 'Bob': 3, 'Charlie': 7}

Utilisez la fonction zip() pour créer un nouveau dictionnaire à partir de chaque liste de clés et de valeurs.

keys = ['k1', 'k2', 'k3']
values = [1, 2, 3]

d = {k: v for k, v in zip(keys, values)}
print(d)
# {'k1': 1, 'k2': 2, 'k3': 3}

Pour d’autres façons de créer des dictionnaires, consultez les articles suivants

Expressions génératrices

Si le crochet [] dans la compréhension de la liste est remplacé par la parenthèse (), le générateur est renvoyé à la place du tuple. C’est ce qu’on appelle une expression génératrice.

Compréhension de la liste :

l = [i**2 for i in range(5)]

print(l)
# [0, 1, 4, 9, 16]

print(type(l))
# <class 'list'>

Expression génératrice :

print() n’affiche pas les éléments du générateur. Vous pouvez obtenir des éléments en utilisant l’instruction for.

g = (i**2 for i in range(5))

print(g)
#  at 0x10af944f8>

print(type(g))
# <class 'generator'>

for i in g:
    print(i)
# 0
# 1
# 4
# 9
# 16

Il est possible d’utiliser if et nest avec des expressions génératrices ainsi que des compréhensions de liste.

g_cells = ((row, col) for row in range(0, 3)
           for col in range(0, 2) if col == row)

print(type(g_cells))
# <class 'generator'>

for i in g_cells:
    print(i)
# (0, 0)
# (1, 1)

Par exemple, si une liste avec de nombreux éléments est créée avec des compréhensions de liste et utilisée dans la boucle for, les compréhensions de liste créent d’abord une liste contenant tous les éléments.

D’autre part, les expressions de générateur créent des éléments un par un après chaque boucle, ce qui permet de réduire l’utilisation de la mémoire.

Vous pouvez omettre les parenthèses () si l’expression du générateur est le seul argument passé à la fonction.

print(sum([i**2 for i in range(5)]))
# 30

print(sum((i**2 for i in range(5))))
# 30

print(sum(i**2 for i in range(5)))
# 30

Il n’y a pas de compréhension des tuples, mais il est possible de créer des tuples en passant l’expression du générateur à tuple().

t = tuple(i**2 for i in range(5))

print(t)
# (0, 1, 4, 9, 16)

print(type(t))
# <class 'tuple'>