Les méthodes append et extend figurent parmi les premières qu’on découvre en manipulant une liste Python. Leur syntaxe se ressemble, leur rôle semble proche, et la confusion persiste souvent bien au-delà des premiers scripts. La différence tient pourtant en une phrase : append ajoute un seul élément à la fin d’une liste, extend déverse tous les éléments d’un itérable un par un.
Derrière cette distinction apparemment simple se cachent des comportements qui changent la structure de vos données, la performance de vos boucles et la lisibilité de votre code.
A lire aussi : Disque dur : quelles différences existe-t-il vraiment ?
Append, extend et la question du type d’élément ajouté
Quand vous appelez ma_liste.append(x), Python prend l’objet x tel quel et le place en dernière position. Peu importe que x soit un entier, une chaîne, un dictionnaire ou une autre liste : il devient un seul élément supplémentaire dans la liste.
Avec extend, le mécanisme diffère. Python itère sur l’objet passé en argument et ajoute chaque élément individuellement. Si vous écrivez ma_liste.extend([10, 20, 30]), la liste reçoit trois nouveaux éléments, pas une sous-liste.
A découvrir également : Quelles étapes comprend un audit informatique typique pour une PME ?
Le piège classique survient lorsqu’on passe une liste à append en pensant fusionner deux listes. Le résultat est une liste imbriquée, ce qui provoque des erreurs silencieuses dans le traitement des données en aval. Tester un print juste après l’opération suffit à repérer le problème, mais en production, cette vérification manque souvent.

Comportement d’extend avec les itérables non séquentiels en Python
Les articles de référence illustrent presque toujours extend avec une liste ou un tuple. La méthode accepte pourtant n’importe quel itérable Python : générateurs, vues de dictionnaires (dict.keys(), dict.values()), ensembles, ou même des objets personnalisés implémentant __iter__.
Cette polyvalence a une conséquence directe sur le code. Plutôt que de convertir un générateur en liste avant de l’injecter, vous pouvez passer le générateur directement à extend. La méthode consomme l’itérable à la volée, ce qui évite de créer une liste intermédiaire en mémoire.
En revanche, passer un générateur à append stocke l’objet générateur lui-même comme élément de la liste, pas les valeurs qu’il produit. C’est un bug fréquent chez les développeurs qui découvrent les générateurs.
extend(range(100))ajoute cent entiers à la liste, sans créer de liste temporaireextend(mon_dict.values())récupère toutes les valeurs d’un dictionnaire directementappend(range(100))ajoute un unique objetrange, pas ses valeursextend("texte")ajoute chaque caractère séparément :['t', 'e', 'x', 't', 'e']
Ce dernier cas surprend régulièrement. Passer une chaîne à extend la décompose caractère par caractère, parce qu’une chaîne est un itérable en Python. Si l’objectif est d’ajouter la chaîne entière, append est le bon choix.
Performance de append et extend sur de grandes listes Python
La documentation officielle Python indique que les listes utilisent une stratégie de surallocation mémoire. Quand la capacité interne est dépassée, Python alloue un bloc plus grand que nécessaire pour que les prochains ajouts ne déclenchent pas systématiquement une réallocation. Ce mécanisme rend append amorti en temps constant par appel.
extend bénéficie du même principe, mais sur l’ensemble des éléments ajoutés en une seule opération. Un appel unique à extend remplace avantageusement une boucle de append parce que la méthode gère la réallocation en bloc, sans repasser par l’interpréteur Python à chaque itération.
Sur des volumes modestes (quelques dizaines d’éléments), la différence de vitesse est négligeable. Elle devient perceptible quand vous ajoutez des milliers d’éléments dans une boucle. Remplacer une boucle for item in data: ma_liste.append(item) par ma_liste.extend(data) réduit le nombre d’appels de fonction et laisse l’implémentation C de CPython travailler directement sur le tableau interne.
Quand la boucle append reste pertinente
Si chaque élément doit être transformé avant insertion (filtrage, conversion de type, validation), la boucle avec append garde sa place. Une list comprehension reste souvent plus rapide dans ce cas, mais append offre plus de flexibilité quand la logique de transformation est complexe ou comporte des effets de bord.
Choisir entre append et extend selon la structure de données
Le choix ne relève pas d’une préférence de style. Il dépend de ce que vous voulez obtenir dans votre liste finale.
- Vous construisez une liste de listes (matrice, tableau de résultats par lot) :
appendpréserve la structure imbriquée - Vous fusionnez plusieurs séquences en une liste plate :
extendaplatit chaque séquence - Vous ajoutez un élément unique (entier, objet, dictionnaire) :
appendest le seul choix logique - Vous videz un générateur ou un itérable dans une liste existante :
extendévite la conversion intermédiaire
La question à se poser est toujours la même : l’argument doit-il devenir un élément de la liste, ou ses éléments doivent-ils devenir des éléments de la liste ? La réponse dicte la méthode.
Un raccourci mnémotechnique qui fonctionne : append ajoute un objet, extend déverse un contenu. Si vous visualisez un seau, append y jette un paquet fermé, extend ouvre le paquet et verse chaque pièce séparément.
Dernier point à garder en tête : les deux méthodes modifient la liste en place et renvoient None. Écrire nouvelle = ma_liste.append(5) affecte None à nouvelle, pas la liste mise à jour. Ce comportement, commun à toutes les méthodes de mutation de liste en Python, provoque un autre type de bug silencieux que ni append ni extend ne vous épargnera.

