Comment copier une liste en Python (copie superficielle ou profonde)

Apprenez à copier une liste en Python. Explorez le découpage de liste, la méthode copy(), les constructeurs de liste et maîtrisez la différence entre les copies superficielles et profondes.

Essayez cette solution dans l'éditeur

Aperçu

En Python, les listes sont des objets mutables et les variables contiennent des références à ces objets en mémoire plutôt que les valeurs réelles. Cela signifie que si vous attribuez une liste à une nouvelle variable (par exemple, `list_b = list_a`), les deux variables font référence exactement à la même liste. Toute modification effectuée via `list_b` affectera immédiatement `list_a`. Pour éviter cet effet secondaire, vous devez créer une copie explicite de la liste.

Python propose plusieurs façons de créer une copie superficielle d'une liste. Une copie superficielle construit une nouvelle liste contenant des références aux éléments trouvés dans la liste d'origine. Les méthodes courantes incluent l'utilisation de la méthode de liste intégrée `.copy()`, l'utilisation du découpage de liste `list_a[:]` ou la transmission de la liste au constructeur `list()`. Tous ces éléments créent un nouveau conteneur de liste, vous permettant d'ajouter ou de supprimer des éléments indépendamment.

Cependant, si une liste contient des objets mutables imbriqués (comme des listes ou des dictionnaires), une copie superficielle ne fera que dupliquer le conteneur externe ; les objets imbriqués restent partagés. La modification d'une liste imbriquée dans la copie modifiera la liste d'origine. Pour éviter cela, vous devez effectuer une copie complète à l'aide de la fonction `deepcopy()` du module `copy`, qui clone de manière récursive chaque objet à l'intérieur de la hiérarchie.

Sortie de code et d'exécution

Ce code illustre le piège d'affectation de référence, la copie superficielle à l'aide de list.copy() et la copie approfondie de listes imbriquées à l'aide du module de copie.

import copy

# 1. The assignment reference trap (Not a copy!)
original = [1, 2, 3]
reference = original
reference.append(99)
print("Reference modification affects original:", original)

# Reset list
original = [1, 2, 3]

# 2. Creating a shallow copy (using list.copy())
shallow_copy = original.copy()
shallow_copy.append(100)
print("\nOriginal:", original)
print("Shallow copy:", shallow_copy)

# 3. The nested list limitation of shallow copies
nested = [[1, 2], [3, 4]]
shallow_nested = nested.copy()
shallow_nested[0].append(99) # Modifying nested list
print("\nOriginal nested:", nested)
print("Shallow nested copy:", shallow_nested)

# 4. Creating a deep copy
nested_original = [[1, 2], [3, 4]]
deep_copy = copy.deepcopy(nested_original)
deep_copy[0].append(99)
print("\nOriginal nested:", nested_original)
print("Deep copy (completely independent):", deep_copy)
Sortie terminale
Reference modification affects original: [1, 2, 3, 99]

Original: [1, 2, 3]
Shallow copy: [1, 2, 3, 100]

Original nested: [[1, 2, 99], [3, 4]]
Shallow nested copy: [[1, 2, 99], [3, 4]]

Original nested: [[1, 2], [3, 4]]
Deep copy (completely independent): [[1, 2, 99], [3, 4]]

Mise en œuvre étape par étape

  • Utilisez my_list.copy() ou my_list[:] pour créer une copie superficielle des structures de liste plate.
  • Évitez les affectations de référence comme copy_list = my_list lorsque vous avez besoin de collections indépendantes.
  • Importez le module de copie et utilisez copy.deepcopy(my_list) pour les listes contenant des structures mutables imbriquées.
  • Assurez-vous de comprendre vos structures de données pour optimiser les performances et l’empreinte mémoire.

Foire aux questions

Quelle est la différence entre une copie superficielle et une copie profonde ?

Une copie superficielle copie le conteneur le plus externe, mais fait référence à des objets mutables imbriqués. Une copie complète duplique de manière récursive tous les conteneurs et objets imbriqués, ce qui donne lieu à des structures de données complètement isolées.

Le découpage de liste (list[:]) est-il plus rapide que list.copy() ?

Leurs performances sont pratiquement identiques puisque les deux exécutent des opérations C optimisées sous le capot. L'utilisation de list.copy() est généralement préférable pour des raisons de lisibilité.

Sujets connexes

Ressources Python recommandées

Développez vos connaissances avec des didacticiels interactifs, des aide-mémoire et des comparaisons de codes associés.