547 votes

Comprendre dict.copy () - peu profond ou profond?

Lors de la lecture de la documentation pour dict.copy(), il dit qu'il fait une copie du dictionnaire. En va de même pour le livre que je suis (Beazley du Python de Référence), qui dit:

La m.copier() la méthode la rend un peu copie des éléments contenus dans un l'objet de mappage et les place dans un une nouvelle cartographie de l'objet.

Réfléchissez à ceci:

>>> original = dict(a=1, b=2)
>>> new = original.copy()
>>> new.update({'c': 3})
>>> original
{'a': 1, 'b': 2}
>>> new
{'a': 1, 'c': 3, 'b': 2}

Donc, je présume que cela permettrait de mettre à jour la valeur de original (et ajouter 'c': 3) depuis que j'ai été faire une copie. Si vous le faites pour une liste:

>>> original = [1, 2, 3]
>>> new = original
>>> new.append(4)
>>> new, original
([1, 2, 3, 4], [1, 2, 3, 4])

Cela fonctionne comme prévu.

Puisque les deux sont des copies, pourquoi est-ce que l' dict.copy() ne fonctionne pas comme prévu? Ou ma compréhension de la faible vs profonde de la copie est défectueux?

1275voto

KennyTM Points 232647

Par "superficielle de la copie", cela signifie que le contenu du dictionnaire n'est pas copié par valeur, mais simplement créer une nouvelle référence.

>>> a = {1: [1,2,3]}
>>> b = a.copy()
>>> a, b
({1: [1, 2, 3]}, {1: [1, 2, 3]})
>>> a[1].append(4)
>>> a, b
({1: [1, 2, 3, 4]}, {1: [1, 2, 3, 4]})

En revanche, une copie en profondeur permet de copier tous le contenu en valeur.

>>> c = copy.deepcopy(a)
>>> a, c
({1: [1, 2, 3, 4]}, {1: [1, 2, 3, 4]})
>>> a[1].append(5)
>>> a, c
({1: [1, 2, 3, 4, 5]}, {1: [1, 2, 3, 4]})

Donc:

  1. a = b: Référence de cession, de Faire a et b des points pour le même objet.

    a ---,
         v
         {1: L}
         ^   |
    b ---'   '----> [1,2,3]
    
  2. a = b.copy(): Peu profonde de la copie, a et b deviendra deux objets isolés, mais leur contenu partagent toujours la même référence

    a ---> {1: L}
               |             
               >---> [1,2,3]
               |
    b ---> {1: M}
    
  3. a = copy.deepcopy(b): Au plus profond de la copie, a et b's de la structure et de contenu deviennent complètement isolé.

    a ---> {1: L}
               ‘-----> [1,2,3]
    b ---> {1: M}
               ‘-----> [1,2,3]
    

51voto

eumiro Points 56644

Prenez cet exemple :

Maintenant nous allons modifier une valeur du niveau « peu profonde » (première) :

Maintenant nous allons changer un valeur d’un niveau plus profond :

42voto

Lie Ryan Points 24517

Ce n'est pas une question de copie profonde ou superficielle, rien de ce que vous faites n'est une copie en profondeur.

Ici:

 >>> new = original 
 

vous créez une nouvelle référence à la liste / dict référencée par l'original.

alors qu'ici

 >>> new = original.copy()
>>> # or
>>> new = list(original) # dict(original)
 

vous créez une nouvelle liste / dict qui est remplie avec une copie des références des objets contenus dans le conteneur d'origine.

5voto

Joril Points 5296

« nouveau » et « original » sont des dicts différents, c’est pourquoi vous pouvez mettre à jour un seul d'entre eux... Les éléments sont une copie peu profonde, pas le dict lui-même.

0voto

Mzialla Points 259
<blockquote> <p>La méthode m.copy() rend une copie superficielle de l’éléments <strong>contenus</strong> dans un objet de mappage et les place dans un nouvel objet de mappage.</p> </blockquote> <p>Procurez-vous le dict <em>fait</em> deepcopied, mais les éléments qu’il ne. Étant donné que les éléments <em>dans</em> le dict sont des entiers, ils se ' deep'copied, puisqu’il n’y a aucune telle chose comme superficielles copies petits entiers.</p> <p><em>Edit : tant pis, voir ci-dessous.</em></p>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X