In Python, you can make a shallow and deep copy with the copy() method of list , dictionary, etc., or the copy() and deepcopy() functions of the copy module.
By "shallow copying" it means the content of the dictionary is not copied by value, but just creating a new reference.
copy() method works in a similar way as the dictionary created using dict. copy() method. So, if there are nested dictionaries and we make a change to any inner dictionary, changes will be reflected in both the copied and original dictionary.
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
>>>
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With