Aller au contenu

Définir une liste en compréhension

Définir une liste en compréhension

On donne ci-dessous un exemple pour illustrer le principe.

  • Pour définir la liste des entiers compris (au sens large) entre l'entier 10 et l'entier 100, on peut écrire:
a = []
for k in range(10,101):
    a.append(k) # append permet d'ajouter un élément en fin de liste

qu'on peut lire ainsi:

a ← liste vide
Pour chaque entier k entre 10 et 100:
    ajouter l'entier k à la fin de la liste a

Python autorise une syntaxe plus concise:

a = [k for k in range(10, 101)]

qu'on peut lire ainsi:

a ← liste des k pour k parcourant les valeurs entières de l'intervalle [10; 101[

Liste d'images

On dispose d'une liste X = [0, 0.3, 0.5, 0.9, 1, 1.5, 2] de nombres et on aimerait disposer de la liste Y des images de ces nombres par la fonction carré x \longmapsto x^2.

Donner une définition de Y par compréhension.

Solution
X = [0, 0.3, 0.5, 0.9, 1, 1.5, 2]
Y = [x**2 for x in X]

Autre transformation des nombres d'une liste

On dispose d'une liste d'entiers X = [2, 7, 9, 64, 15, 42, 73].

On veut définir une liste Y dans laquelle chacun des entiers de la liste X est remplacé par sa moitié s'il est pair et par son double s'il est impair.

Donner une définition de Y en compréhension.

Solution

On définit au préalable une fonction traduisant la transformation demandée sur un entier:

def f(n):
    """
    n -- entier
    """
    if n%2 == 0: return n//2
    else: return 2*n

On peut alors définir Y ainsi:

X = [2, 7, 9, 64, 15, 42, 73]
Y = [f(x) for x in X]

Définir une liste d'entiers choisis au hasard

Note

La fonction randint du module random permet de générer des entiers au hasard. randint(a,b) (où a et b sont des entiers, a ≤ b) choisit un entier au hasard entre a et b (bornes a et b comprises).

Par exemple random.randint(-10, 10) donne un entier au hasard entre -10 et 10.

Définir une liste en compréhension afin qu'elle contienne 20 entiers choisis au hasard entre -10 et 10.

Solution

Une liste de longueur 20 avec des éléments au hasard entre -10 et 10:

>>> from random import randint
>>> A = [randint(-10,10) for _ in range(20)]
>>> A
[-1, 2, -5, -4, -10, -10, 2, -10, 2, 9, 5, 1, -8, 6, 1, 10, -3, 1, 1, 2]
>>> A = [randint(-10,10) for _ in range(20)]
>>> A
[-3, 6, 9, -2, 10, -7, -9, 3, 2, 8, 1, 4, 10, -10, 8, 8, 10, -4, -7, -2]

Remarque

On a utilisé _ comme nom de variable parcourant 0, 1, ..., 19 ci-dessus. Un nom de variable peut en effet commencer par un underscore en langage python. Et on peut choisir l'underscore seul. On l'utilisera quand on a besoin, comme ici, d'un nom de variable "anonyme": la syntaxe pour parcourir les valeurs de 0 à 19 (range(20)) demande en effet explicitement un nom de variable, mais cette variable n'est pas utilisée ici explicitement (elle ne sert que de compteur sous-jacent pour être certain de créer 20 valeurs), un nom "anonyme" tel que l'underscore permet de souligner cette absence de rôle autre que contrôler le nombre d'exécutions du corps de boucle.

Rappel sur le nommage des variables en Python

Rappelons ici les règles de nommage des variables python.

Le nom d'une variable en Python peut être constitué de lettres minuscules (a à z), de lettres majuscules (A à Z), de nombres (0 à 9) ou du caractère souligné (_). Vous ne pouvez pas utiliser d'espace dans un nom de variable.

Un nom de variable ne doit pas débuter par un chiffre.
En général, ne faîtes pas débuter un nom de variable par le caractère _ car ce choix a une signification dans le monde de la programmation python, que vous découvrirez plus tard.

Il faut absolument éviter d'utiliser un mot « réservé » par Python comme nom de variable (par exemple : print, range, for, from, etc.) car vous redéfiniriez alors localement ce nom, ce qui peut être source de bugs.

Enfin, Python est sensible à la casse, ce qui signifie que les variables TesT, test ou TEST sont différentes.

Copie de liste

Proposer un code qui permette de copier une liste A dans une liste B.

Important

Si l'on dispose d'une liste A, le code B = A ne copie pas A dans B. Ce code consiste à donner un second nom à la même liste. On a ainsi un seul objet en mémoire, qui porte deux noms.

Dans l'exercice, on veut deux objets, l'un s'appelle A, l'autre B. Et leurs contenus sont les mêmes.

Si l'on compare une liste à une bouteille:

  • Avec B = A, notre bouteille porte les étiquettes A et B.
  • Tandis que dans l'exercice, on veut une bouteille étiquetée A, une bouteille étiquetée B, mais les deux bouteilles ont des contenus identiques (par exemple toutes deux contiennent un litre de lait).

Nous revenons sur ce principe dans les pages suivantes.

Par exemple:

>>> A = [42, 666, 1789]
>>> B = copie(A)
>>> B
[42, 666, 1789]
>>> B is A # B et A ne sont pas le même objet
False
>>> B == A # B et A ont le même contenu
True
Un code
def copie(tab):
    """
    tab -- liste

    renvoie une liste de même contenu que tab

    """
    return [element for element in tab]

Si l'on n'a pas besoin d'une fonction, on peut écrire directement:

B = [elt for elt in A]

Note

Lorsque les éléments de A sont eux-mêmes des listes, cette fonction de copie ne fonctionnerait pas tout à fait comme attendu... Nous en reparlerons.

Transformer une chaîne de caractères en liste de caractères

Ecrire un corps pour la fonction:

def deChaineEnListe(chaine):
    """
    chaine -- chaine de caractères
    renvoie une liste dont les éléments 
    sont les caractères de la chaîne, dans le même ordre.
    """

Exemple d'utilisation:

>>> deChaineEnListe('abracadabra')
['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a']
Solution
def deChaineEnListe(chaine):
    """
    chaine -- chaine de caractères
    renvoie une liste dont les éléments sont les caractères de la chaîne, dans le même ordre.
    """
    return [caractere for caractere in chaine]