I would like to make a deep copy of a dict in python. Unfortunately the .deepcopy() method doesn’t exist for the dict. How do I do that?
>>> my_dict = {'a': [1, 2, 3], 'b': [4, 5, 6]}
>>> my_copy = my_dict.deepcopy()
Traceback (most recent calll last):
File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'deepcopy'
>>> my_copy = my_dict.copy()
>>> my_dict['a'][2] = 7
>>> my_copy['a'][2]
7
The last line should be 3.
I would like that modifications in my_dict don’t impact the snapshot my_copy.
How do I do that? The solution should be compatible with Python 3.x.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
How about:
import copy
d = { ... }
d2 = copy.deepcopy(d)
Python 2 or 3:
Python 3.2 (r32:88445, Feb 20 2011, 21:30:00) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import copy
>>> my_dict = {'a': [1, 2, 3], 'b': [4, 5, 6]}
>>> my_copy = copy.deepcopy(my_dict)
>>> my_dict['a'][2] = 7
>>> my_copy['a'][2]
3
>>>
Method 2
dict.copy() is a shallow copy function for dictionary
id is built-in function that gives you the address of variable
First you need to understand “why is this particular problem is happening?”
In [1]: my_dict = {'a': [1, 2, 3], 'b': [4, 5, 6]}
In [2]: my_copy = my_dict.copy()
In [3]: id(my_dict)
Out[3]: 140190444167808
In [4]: id(my_copy)
Out[4]: 140190444170328
In [5]: id(my_copy['a'])
Out[5]: 140190444024104
In [6]: id(my_dict['a'])
Out[6]: 140190444024104
The address of the list present in both the dicts for key ‘a’ is pointing to same location.
Therefore when you change value of the list in my_dict, the list in my_copy changes as well.
Solution for data structure mentioned in the question:
In [7]: my_copy = {key: value[:] for key, value in my_dict.items()}
In [8]: id(my_copy['a'])
Out[8]: 140190444024176
Or you can use deepcopy as mentioned above.
Method 3
Python 3.x
from copy import deepcopy
my_dict = {'one': 1, 'two': 2}
new_dict_deepcopy = deepcopy(my_dict)
Without deepcopy, I am unable to remove the hostname dictionary from within my domain dictionary.
Without deepcopy I get the following error:
"RuntimeError: dictionary changed size during iteration"
…when I try to remove the desired element from my dictionary inside of another dictionary.
import socket import xml.etree.ElementTree as ET from copy import deepcopy
domain is a dictionary object
def remove_hostname(domain, hostname):
domain_copy = deepcopy(domain)
for domains, hosts in domain_copy.items():
for host, port in hosts.items():
if host == hostname:
del domain[domains][host]
return domain
Example output:
[orginal]domains = {‘localdomain’: {‘localhost’: {‘all’: ‘4000’}}}
[new]domains = {‘localdomain’: {} }}
So what’s going on here is I am iterating over a copy of a dictionary rather than iterating over the dictionary itself. With this method, you are able to remove elements as needed.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0