Aller au contenu

1NSI : cours Listes Python⚓︎

Introduction⚓︎

Liste

Une Liste est un conteneur (modifiable/mutable) d'éléments ordonnés.

C'est une structure de données primitive de Python, qui est un type construit donc un conteneur/collections d'éléments.

Les types des éléments d'une liste :

  • peuvent être variables pour certains langages, dits à typage dynamique (Python, ..),
  • ou pas, pour certains autres langages, dits à typage statique (langage C, Java, etc..)

Exp

On définit une liste avec des crochets []

>>> liste = [2,3,7,5.4,"Bonjour"]

Fonctions utiles sur les Listes⚓︎

Longueur d'une Liste⚓︎

>>> l = [4,3,6.1,8,5,10]
>>> len(l)  # renvoie le nombre d'éléments/objets de la liste
6

len renvoie la longueur de la liste

Liste Vide⚓︎

>>> l = [] # est la liste 'VIDE' qui est de type 'list',
         # et qui ne contient aucun élément
>>> len(l)
0        # la longueur de la liste vide vaut 0

ou bien (équivalent pour définir une liste vide) :

>>> l = list()

Appartenance à une Liste avec in, ou pas, avec not in⚓︎

>>> liste = [8,2,6,1,3,4,5]
>>> 2 in liste
True
>>> 7 in liste
False
>>> [1,3] in liste
False
>>> liste = [8,2,6,[1,3],4,5]
>>> [1,3] in liste
True
# ou bien NON appartenance avec les mots-clés `not in`
>>> 2 not in liste
False

Indices / Index⚓︎

Indices positifs⚓︎

>>> liste=[6,5,2,7.4,"Bonjour"]
>>> liste[1]  # renvoie le caractère à l'indice 1, ici: 5
>>> liste[0]  # renvoie le 1er élément, càd l'élément à l'indice 0

Indices négatifs⚓︎

>>> liste[-1]  # renvoie le dernier élément
>>> liste[-2]  # renvoie l'avant-dernier élément

Tranches / Slices ou Slicing⚓︎

Tranches / Slicing simple (avec 2 arguments)⚓︎

>>> liste = [8,7,2,5,10,16,6,3,18]
>>> liste[3:7]  # renvoie tous les caractères dont les indices
                # sont compris entre 3 inclus 
                # et 7-1=6 inclus (donc 7 NON inclus)

Tranches / Slicing étendu (avec un 3ème argument pas/step optionnel)⚓︎

>>> liste[3:6:2]  # renvoie tous les éléments dont les indices
                  # sont compris entre 3 inclus 
                  # et 5 inclus (c'est-à-dire 6 NON inclus)
                  # mais seulement tous les 2 caractères, avec un pas=2

Exp

>>> liste[:6:2]    # tous les éléments depuis le tout début
                  # jusqu'à celui d'indice 5 inclus (c'est-à-dire 6 NON inclus)
                  # mais seulement tous les 2 éléments, avec un pas=2
>>> liste[3::2]    # tous les éléments depuis celui d'indice 3 inclus
                  # jusqu'à la toute fin de la liste
                  # mais seulement tous les 2 éléments, avec un pas=2
>>> liste[::2]     # tous les éléments depuis le tout début
                  # jusqu'à la toute fin de la liste
                  # mais seulement tous les 2 éléments, avec un pas=2
>>> liste[::-1]    # tous les éléments depuis le tout début
                  # jusqu'à la toute fin de la liste
                  # avec un pas=-1, donc écrit à l'envers...
>>> liste[5:2:-1]  # tous les éléments depuis celui d'indice 5
                  # jusqu'à celui d'indice 2 NON INCLUS
                  # avec un pas=-1, donc écrit à l'envers...

Les Listes sont des séquences⚓︎

Les listes disposent d'indices entiers, et d'une fonction len() donc :

Pte

Les listes list sont des séquences.

Techniques de parcours de Listes⚓︎

Technique 1 : élément par élément, SANS indices⚓︎

liste = [8,6,9,5,3,10,2,4,7]
for element in liste:
  print(element)

Pte

Les listes list sont des itérables.

Technique 2 : élément par élément, AVEC des indices⚓︎

liste = [8,6,9,5,3,10,2,4,7]
for i in range(len(liste)):
  print(liste[i])

Les listes sont des séquences, donc elles sont itérables.

Utilisation des Listes pour stocker des Tableaux de Nombres/Matrices⚓︎

Disons que l'on souhaite stocker en mémoire la matrice de nombres

    A = 1  4  6  8
       -2  3  5 -1
        8 10  9  7

Comment faire? Quel type de données utiliser?

>>> A = [[1,4,6,8],[-2,3,5,-1],[8,10,9,7]]

Du coup, comment accéder à chacun des éléments du Tableau à 2 Dimensions?

Par exemple, pour accéder à l'élément 4, il faut taper la ligne commande/l'instruction:

>>> A[0][1]

Ex

Quelles instructions faut-il taper pour accéder aux éléments suivants?

  • 3? 5? 8? 7?

>>> A[1][1] = 3
>>> A[1][2] = 5
>>> A[2][0] = 8
>>> A[2][3] = 7

Remarque Lorsqu'on dispose d'une liste de sous-liste, de dimension 2 (par exemple la liste A de l'exercice précédent). Dans ce cas: A[i][j] représente l'élément situé : * à la ligne d'indice i * à la colonne d'indice j

Méthodes sur les Listes⚓︎

Méthodes usuelles⚓︎

Voici quelques exemples d'utilisation de quelques méthodes utiles sur les Listes. Notons liste une liste. liste=[1,5,7,2,15,8]

  • liste.append(9) ajoute l'élément 9 en fin de liste (à l'extrémité droite). liste.append("Bonjour")
    ATTENTION : ne PAS écrire liste = liste.append(9) qui écrase totalement la variable liste (qui devient None) Par contre cette méthode ne permet d'ajouter qu'un seul élément. Pour en ajouter plusieurs d'un coup:
  • liste.extend([10,12]) ajoute les deux éléments 10 et 12 en fin de liste (à l'extrémité droite). renvoie [1,5,7,2,15,8,"Bonjour",10,12]
  • liste.index(5) renvoie :

    • le 1er indice où se trouve 5 dans la liste liste
    • ou bien une erreur s'il ne trouve PAS 5 dans liste

    Forme Générale: liste.index(el,[,start[,end]]) cherche la 1ère occurence de el dans liste, pour des indices compris entre start (et end)

  • liste.insert(2,6) insère l'élément 6 à l'indice 2

  • liste.remove(6) supprime (seulement) le premier élément 6 dans liste
  • liste.clear() supprime toute la liste: équivalent à del liste[:]
  • liste.count(6) compte le nombre d'occurences de 6 dans phrase
  • liste.pop([i]) récupère l'élément d'indice i tout en le supprimant de la liste. Par défaut, si aucune valeur du paramètre i n'est passée, c'est le dernier élémént (le plus à droite) de la liste qui est récupéré et supprimé.
  • liste.sort(*, key=None, reverse=False) trie (en place) les éléments de la liste. Les arguments passés en paramètres permettent de personnaliser le tri.
  • liste.reverse() renverse la liste dans l'ordre contraire, c'est-à-dire réécrit tous les éléments de la liste, mais de droite à gauche.

Liste Complète des Méthodes sur les Listes⚓︎

Aide en ligne⚓︎

Vous trouverez une Liste Complète de TOUTES les Méthodes opérant sur les Listes, sur cette page de la Documentation Officielle

Aide en Local (dans un Interpréteur Python)⚓︎

  1. Dans un interpréteur Python, dir(list) affiche la liste complète de toutes les méthodes disponibles sur les listes list, y compris les méthodes magiques/spéciales (cf ci-dessous), mais elles ne sont pas documentées (ni signature, ni docstring).

  2. Dans un interpréteur Python, help(list) affiche la liste complète de toutes les méthodes disponibles sur les Listes list, y compris les méthodes magiques/spéciales (cf ci-dessous), AVEC DOCUMENTATION: AVEC LEURS SIGNATURES ET LES DOCSTRINGS.

Méthodes magiques / Méthodes spéciales sur les Listes⚓︎

Méthodes magiques / Méthodes spéciales sur les Listes

Parmi toutes les méthodes disponibles affichées par dir(list), certaines sont encadrées par deux underscores (de chaque côté) __unCertainNom__() : Elles sont appelées des méthodes magiques ou méthodes spéciales sur les listes. En pratique cela signifie que :

  • elles sont accessibles via la syntaxe normale pour les méthodes : nomListe.__nomMethodeMagique__()
  • elles sont également accessibles via une syntaxe spéciale / magique (qui dépend de la méthode en question)

de Méthodes magiques / Méthodes spéciales sur les Listes

On se donne deux listes l1=[1,2,3,4] et l2=[5,6,7]

  • __len()__ : calcule la longueur d'une liste ...
    • Syntaxe normale : l2.__len__() renvoie le nombre \(3\)
    • Syntaxe spéciale : len(l2) renvoie le nombre \(3\)
  • __eq()__ : teste l'égalité entre deux listes ...
    • Syntaxe normale : l1.__eq__(l2) renvoie False car l1 et l2 ne sont pas égales
    • Syntaxe spéciale : l1 == l2 renvoie False (pour les mêmes raisons)
      Principe Général : À chaque fois qu'on veut tester l'égalité entre deux listes avec le symbole ==, c'est en fait la méthode magique __eq__() qui est appelée pour tester l'égalité.

Voici quelques autres méthodes magiques sur les listes :

  • __ne__() veut dire \(\ne\) : "Not Equal to" c'est-à-dire Non égal, donc ! = en Python
  • __gt__() veut dire \(\gt\) : "Greater Than" c'est-à-dire Supérieur Strictement
  • __ge__() veut dire \(\ge\) : "Greater than or Equal to" c'est-à-dire Supérieur ou égal à
  • __lt__() veut dire \(\lt\) : "Less Than" c'est-à-dire Inférieur Strictement
  • __le__() veut dire \(\le\) : "Less than or Equal to" c'est-à-dire Inférieur ou égal
  • __add__() correspond à l'opération + : pour la concaténation de deux listes
  • __mul__() correspond à l'opération * : pour la multiplication entre une liste et un entier
  • __contains__() correspond au mot-clé in utilisé pour tester l'inclusion d'une liste dans une autre
  • ⚠ __repr__() ⚠ représente une liste dans un interpréteur Python, c'est-à-dire qu'il affiche une liste dans un interpréteur Python, sous un certain format spécifique. Elle est appelée quand on tape dans l'interpréteur :
  • ou bien >>> l1 \(\quad\) (où l1 désigne le nom d'une liste)
  • ou bien >>> print(l1)
  • ⚠ __str__() ⚠ représente une liste dans un interpréteur Python, c'est-à-dire qu'il affiche une liste dans un interpréteur Python, sous un certain format spécifique, mais seulement pour le print()
  • >>> print(l1)
  • etc...

Opérations Arithmétiques sur les Listes⚓︎

Addition⚓︎

>>> l1 = [4,6,8]
>>> l2 = [3,5,7,9]
>>> l1 + l2   # ceci est la CONCATÉNATION de l1 et l2
[4,6,8,3,5,7,9]

ATTENTION : Pas de Soustraction

Multiplication⚓︎

>>> l1 = [4,6,8]
>>> l1 * 2
[4, 6, 8, 4, 6, 8]

ATTENTION :

  • le produit de deux listes n'existe pas
  • Pas de Division

Les listes sont mutables⚓︎

Par exemple, on peut modifier directement un élément d'une liste list in situ, par affectation directe, EN CONSERVANT LA MÊME ADRESSE MÉMOIRE (qui est en fait un pointeur vers le début de la liste). On dit dans ce cas, que les listes supportent l'affection d'éléments 🇫🇷 ou les item assignment 🇬🇧 :

>>> l = [4,3,6,8,5,10]
>>> id(l) # renvoie l'adresse mémoire du début de la liste
# Exemple de réponse:
140034881798976
# affectation d'élément / item assignment :
>>> l[1] = 7
>>> id(l) # la 'nouvelle' adresse mémoire de la liste, après modification 
          # (ici, affectation d'élément), est inchangée
140034881798976

Plus généralement, on peut modifier le contenu d'une variable de type liste in situ, c'est-à-dire EN CONSERVANT LA MÊME ADRESSE MÉMOIRE: Par exemple avec une méthode l.append(2)

>>> l = [4,3,6,8,5,10]
>>> id(l) # renvoie l'adresse mémoire du début de la liste
# Exemple de réponse:
140034881798976
# ajout d'élément en fin de liste :
>>> l.append(2)
>>> id(l) # la 'nouvelle' adresse mémoire de la liste, après modification
      # (ici, ajout d'élément en fin de liste), est inchangée
140034881798976

On s'aperçoit que les deux adresses mémoires, ou pointeurs, AVANT et APRÈS modification de la liste, sont encores égales.

Mutabilité des Listes

Les listes sont mutables.

Remarque Le fait que les listes soient mutables laisse à penser qu'il s'agit d'un type (/structure) de données Python spécialement prévu pour être modifiable avec une bonne efficacité.

Pte

TOUS les autres types de données Python (connus pour le moment), sont immutables. Cela veut dire que l'on ne peut pas les modifier sans avoir à recréer une nouvelle adresse mémoire. En particulier, sont immutables les types suivants:

  • bool les booléens sont immutables
  • int les entiers sont immutables
  • float les flottants sont immutables
  • str les chaînes de caractères sont immutables

Compréhensions de Listes⚓︎

Une compréhension de liste, ou liste en compréhension, est une syntaxe pour créer/générer une liste en une seule ligne de commande, en y incluant une boucle for sur une seule ligne.

Syntaxe sans if⚓︎

# 'iterable' désigne un itérable: une chaîne, ou une liste (etc...)
[fonction(item) for item in iterable]

Exp

>>> [i for i in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Syntaxe avec un if :⚓︎

# 'iterable' désigne un itérable: une chaîne, ou une liste (etc...)
[fonction(item) for item in iterable if condition(item)]

Exp

# tous les nombres entre 0 et 20 inclus, mais NON divisibles par 4
>>> [x for x in range(21) if x%4!=0]
[1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18, 19]

REMARQUE / ATTENTION Le if DOIT être placé APRÈS le for, du moins lorsque le if est tout seul (c'est-à-dire non accompagné d'un else). En particulier, la syntaxe suivante, que l'on pourrait naïvement croire équivalente, NE FONCTIONNE PAS:

# ATTENTION : ERREUR DE SYNTAXE
>>> [i if x%4!=0 for i in range(21)]
SyntaxError: invalid syntax

Syntaxe avec un if ET un else⚓︎

# 'iterable' désigne un itérable: une chaîne, ou une liste (etc...)
[fonction(item) if condition(item) else autreFonction(item) for item in iterable]

Exp

# Tous les nombres entre 0 et 20 inclus, sauf les multiples de 4 qui sont quant à eux, remplacés par 'bissextiles"
>>> [i if i%4!=0 else "bissextile" for i in range(21)]
['bissextile', 1, 2, 3, 'bissextile', 5, 6, 7, 'bissextile', 9, 10, 11, 
'bissextile', 13, 14, 15, 'bissextile', 17, 18, 19, 'bissextile']

REMARQUE / ATTENTION Le if ET le else DOIVENT être placés DEVANT le for. En particulier, la syntaxe suivante, que l'on pourrait naïvement croire équivalente, NE FONCTIONNE PAS:

# ATTENTION : ERREUR DE SYNTAXE
>>> [i for i in range(2100) if i%4!=0 else "bissextile"]
SyntaxError: invalid syntax