En lisant la documentation de dict.copy()
, il indique qu'il crée une copie superficielle du dictionnaire. Il en va de même pour le livre que je suis (Beazley's Python Reference), qui dit:
La méthode m.copy () crée une copie superficielle des éléments contenus dans un objet de mappage et les place dans un nouvel objet de mappage.
Considère 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}
J'ai donc supposé que cela mettrait à jour la valeur de original
(et ajouterait 'c': 3) également puisque je faisais une copie superficielle. Comme 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 superficielles, pourquoi est-ce que dict.copy()
cela ne fonctionne pas comme je m'y attendais? Ou ma compréhension de la copie superficielle vs profonde est défectueuse?
la source
Réponses:
Par "copie superficielle", cela signifie que le contenu du dictionnaire n'est pas copié par valeur, mais simplement en créant une nouvelle référence.
En revanche, une copie complète copiera tous les contenus par valeur.
Donc:
b = a
: Affectation de référence, marquea
etb
pointe vers le même objet.b = a.copy()
: Copie superficielle,a
etb
deviendra deux objets isolés, mais leur contenu partagera toujours la même référenceb = copy.deepcopy(a)
: Copie profonde,a
etb
la structure et le contenu deviennent complètement isolés.la source
L
nouveau dansb
. Cela simplifierait l'exemple.b[1][0] = 5
. Sib
c'est une copie superficielle, vous venez de changera[1][0]
.Ce n'est pas une question de copie profonde ou de copie superficielle, rien de ce que vous faites n'est une copie profonde.
Ici:
vous créez une nouvelle référence à la liste / dict référencée par l'original.
ici:
vous créez une nouvelle liste / dict qui est remplie d'une copie des références des objets contenus dans le conteneur d'origine.
la source
Prenez cet exemple:
Modifions maintenant une valeur au niveau (peu profond) (premier):
Modifions maintenant une valeur d'un niveau plus en profondeur:
la source
no change in original, since ['a'] is an immutable integer
Cette. Il répond en fait à la question posée.Ajout à la réponse de kennytm. Lorsque vous effectuez une copie superficielle parent.copy (), un nouveau dictionnaire est créé avec les mêmes clés, mais les valeurs ne sont pas copiées, elles sont référencées.Si vous ajoutez une nouvelle valeur à parent_copy, cela n'affectera pas parent car parent_copy est un nouveau dictionnaire pas de référence.
La valeur de hachage (id) du parent [1] , parent_copy [1] sont identiques, ce qui implique [1,2,3] du parent [1] et parent_copy [1] stockés à l'ID 140690938288400.
Mais le hachage de parent et parent_copy sont différents, ce qui implique que ce sont des dictionnaires différents et parent_copy est un nouveau dictionnaire ayant des valeurs faisant référence aux valeurs de parent
la source
"nouveau" et "original" sont des dict différents, c'est pourquoi vous pouvez mettre à jour un seul d'entre eux .. Les éléments sont copiés en profondeur, pas le dict lui-même.
la source
Le contenu est copié peu profond.
Donc, si l'original
dict
contient unlist
ou un autredictionary
, en modifier un dans l'original ou sa copie superficielle les modifiera (lelist
ou ledict
) dans l'autre.la source
Dans votre deuxième partie, vous devez utiliser
new = original.copy()
.copy
et=
sont des choses différentes.la source