Lorsque vous utilisez Python, vous vous retrouvez à utiliser my_list.pop() pour retirer le dernier élément d'une liste, ou my_dict.pop('key') pour retirer un élément d'un dictionnaire, découvrant ainsi que vous utilisez .pop() sur divers objets.

On a parfois l'impression que pop() est une méthode d'instance universelle que l'on peut attacher à n'importe quel objet. Quelle est donc la nature de cette méthode pop() ?


1. 'pop()' n'est pas unique



En résumé, pop() des listes et pop() des dictionnaires sont des méthodes complètement différentes, bien que leurs noms soient identiques.

  • La classe list définit sa propre méthode pop() adaptée aux listes.

  • La classe dict définit également sa propre méthode pop() adaptée aux dictionnaires.

  • Il en va de même pour la classe set.

Le fait que des objets différents aient des méthodes portant le même nom est fortement lié à une des caractéristiques orientées objet de Python : le polymorphisme. Le nom 'pop' partage simplement un sens conventionnel de "retirer (pop) un élément d'une structure de données et le retourner".


2. Différentes façons de fonctionner pour les pop() de chaque classe

Le fait qu'elles aient le même nom ne signifie pas qu'elles fonctionnent de la même manière. Chaque classe a implémenté pop() selon sa structure de données.

1. list.pop([index])

  • Fonctionnement : Retire et retourne l'élément à un index spécifique (index) dans la liste.

  • Caractéristique : Si aucun index n'est spécifié, la valeur par défaut -1 est appliquée, retirant ainsi le dernier élément. Cela correspond à l'opération 'pop' dans les structures de données de type pile (Stack).

  • Exemple :

my_list = ['a', 'b', 'c']

# Pas d'index spécifié (retire le dernier élément 'c')
last_item = my_list.pop()
print(f"Valeur retournée : {last_item}, liste restante : {my_list}")
# Sortie : Valeur retournée : c, liste restante : ['a', 'b']

# Index 0 spécifié (retire 'a')
first_item = my_list.pop(0)
print(f"Valeur retournée : {first_item}, liste restante : {my_list}")
# Sortie : Valeur retournée : a, liste restante : ['b']

2. dict.pop(key[, default])

  • Fonctionnement : Retire et retourne l'élément correspondant à une clé (key-value pair) dans le dictionnaire.

  • Caractéristique : Contrairement à list.pop(), il est obligatoire de fournir une clé (key). Si la clé n'existe pas et qu'une valeur default est fournie, cette valeur est retournée ; sinon, une KeyError se produit.

  • Exemple :

my_dict = {'apple': 1, 'banana': 2}

# Retire la clé 'apple'
item = my_dict.pop('apple')
print(f"Valeur retournée : {item}, dictionnaire restant : {my_dict}")
# Sortie : Valeur retournée : 1, dictionnaire restant : {'banana': 2}

# Tentative de retirer une clé inexistante ('grape') (valeur par défaut 99 retournée)
default_item = my_dict.pop('grape', 99)
print(f"Valeur retournée : {default_item}, dictionnaire restant : {my_dict}")
# Sortie : Valeur retournée : 99, dictionnaire restant : {'banana': 2}

3. set.pop()

  • Fonctionnement : Retire et retourne un élément aléatoire du set.

  • Caractéristique : Étant donné que le set est une structure de données non ordonnée, il n'est pas possible de prédire quel élément sera retiré. pop() ne prend aucun argument.

  • Exemple :

my_set = {10, 20, 30}

# Retire un élément aléatoire (aucune manière de savoir quel sera le résultat)
item = my_set.pop()
print(f"Valeur retournée : {item}, set restant : {my_set}")
# Sortie possible 1: Valeur retournée : 10, set restant : {20, 30}
# Sortie possible 2: Valeur retournée : 20, set restant : {10, 30}

3. Pourquoi cela semble-t-il "coller partout" ?



Penser que nous utilisons pop() comme si c'était une "méthode d'instance" est tout à fait exact. pop() est en fait une méthode qui appartient à chaque objet (instance) spécifique.

Bien qu'il ressemble à obj.pop(), cela ne signifie pas que pop() est une fonction globale ou qu'elle est définie dans la classe parente de tous les objets. Lorsque Python appelle obj.method(), il vérifie dynamiquement si l'objet obj possède un attribut (méthode) nommé method.

  • my_list est une instance de la classe list, et la classe list a la méthode pop définie.

  • my_dict est une instance de la classe dict, et la classe dict a également la méthode pop définie.

Voilà pourquoi my_list.pop() et my_dict.pop() fonctionnent tous les deux.

Que se passe-t-il si on essaie d'appeler pop() sur un objet sans cette méthode définie ? Comme prévu, une AttributeError se produira. Prenons, par exemple, un tuple.

# Le tuple n'étant pas mutable, il n'a pas de méthode pop().
my_tuple = (1, 2, 3)

# AttributeError: l'objet 'tuple' n'a pas d'attribut 'pop'
my_tuple.pop() 

Une infographie illustrant la méthode pop() en Python à travers trois structures de données

Résumé

  1. pop() n'est pas une fonction globale de Python ni une méthode commune.

  2. list, dict, set, sont des méthodes définies individuellement par chaque classe de conteneur.

  3. La raison pour laquelle elles portent le même nom est qu'elles partagent le sens conventionnel de "retirer et retourner des données".

  4. Étant donné que leur fonctionnement varie d'une classe à l'autre, list utilise un index, dict une clé et set retire des éléments aléatoirement.