In Depth et un moyen facile de s'en souvenir :
Chaque fois que vous faites dict2 = dict1, dict2 fait référence à dict1. Les deux dict1 et dict2 pointent vers le même emplacement dans la mémoire. Il s'agit d'un cas normal lorsque vous travaillez avec des objets mutables en Python. Lorsque vous travaillez avec des objets mutables en Python, vous devez être prudent car il est difficile de déboguer.
Au lieu d'utiliser dict2 = dict1, vous devriez utiliser copie (copie superficielle) et copie profonde de la méthode python copie pour séparer le dict2 du dict1.
Le bon chemin est :
>>> dict1 = {"key1": "value1", "key2": "value2"}
>>> dict2 = dict1.copy()
>>> dict2
{'key1': 'value1', 'key2': 'value2'}
>>> dict2["key2"] = "WHY?"
>>> dict2
{'key1': 'value1', 'key2': 'WHY?'}
>>> dict1
{'key1': 'value1', 'key2': 'value2'}
>>> id(dict1)
140641178056312
>>> id(dict2)
140641176198960
>>>
Comme vous pouvez le constater, le id de dict1 et dict2 sont différentes, ce qui signifie que les deux pointent/référencent des emplacements différents dans la mémoire.
Cette solution fonctionne pour les dictionnaires avec des valeurs immuables, ce n'est pas la bonne solution pour ceux avec des valeurs mutables.
Eg :
>>> import copy
>>> dict1 = {"key1" : "value1", "key2": {"mutable": True}}
>>> dict2 = dict1.copy()
>>> dict2
{'key1': 'value1', 'key2': {'mutable': True}}
>>> dict2["key2"]["mutable"] = False
>>> dict2
{'key1': 'value1', 'key2': {'mutable': False}}
>>> dict1
{'key1': 'value1', 'key2': {'mutable': False}}
>>> id(dict1)
140641197660704
>>> id(dict2)
140641196407832
>>> id(dict1["key2"])
140641176198960
>>> id(dict2["key2"])
140641176198960
Vous pouvez voir que même si nous avons appliqué la copie pour dict1, la valeur de mutable est changée en false à la fois sur dict2 et dict1, même si nous ne la changeons que sur dict2. C'est parce que nous avons changé la valeur d'une partie de dict mutable de dict1. Lorsque nous appliquons une copie sur dict, elle ne fera qu'une copie superficielle, ce qui signifie qu'elle copie toutes les valeurs immuables dans un nouveau dict et ne copie pas les valeurs mutables, mais elle les référencera.
La solution ultime est de faire une copie profonde de dict1 pour créer complètement un nouveau dict avec toutes les valeurs copiées, y compris les valeurs mutables.
>>>import copy
>>> dict1 = {"key1" : "value1", "key2": {"mutable": True}}
>>> dict2 = copy.deepcopy(dict1)
>>> dict2
{'key1': 'value1', 'key2': {'mutable': True}}
>>> id(dict1)
140641196228824
>>> id(dict2)
140641197662072
>>> id(dict1["key2"])
140641178056312
>>> id(dict2["key2"])
140641197662000
>>> dict2["key2"]["mutable"] = False
>>> dict2
{'key1': 'value1', 'key2': {'mutable': False}}
>>> dict1
{'key1': 'value1', 'key2': {'mutable': True}}
Comme vous pouvez le voir, les id sont différents, ce qui signifie que dict2 est un nouveau dict avec toutes les valeurs de dict1.
La copie profonde doit être utilisée si vous souhaitez modifier l'une des valeurs mutables sans affecter le dict original. Sinon, vous pouvez utiliser la copie superficielle. Deepcopy est lent car il travaille de manière récursive pour copier toutes les valeurs imbriquées dans le dict original et prend également de la mémoire supplémentaire.
11 votes
PythonTutor est idéal pour visualiser les références Python. Voici ce code à la dernière étape . Vous pouvez voir
dict1
ydict2
pointent vers le même dictateur.3 votes
Juste au cas où PythonTutor tomberait en panne, voici une capture d'écran des structures de données à la fin.