Я хотел бы сделать глубокую копию dict
в Python. К сожалению, .deepcopy()
метод не существует для dict
. Как я могу это сделать?
>>> 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
Последняя строка должна быть 3
.
Я хотел бы, чтобы изменения my_dict
не влияли на снимок my_copy
.
Как я могу это сделать? Решение должно быть совместимо с Python 3.x.
python
python-3.x
Оливье Грегуар
источник
источник
Ответы:
Как насчет:
Python 2 или 3:
источник
copy.deepcopy
что не является потокобезопасным. Узнал это трудным путем. С другой стороны, в зависимости от вашего варианта использования,json.loads(json.dumps(d))
является потокобезопасным и работает хорошо.json.loads
, что проблема не решается во всех случаях, когдаdict
атрибуты python не сериализуемы в JSON. Это может помочь тем, кто имеет дело только с простыми структурами данных, например, из API, но я не думаю, что этого решения достаточно, чтобы полностью ответить на вопрос ОП.dict.copy () - функция поверхностного копирования для словаря.
id - встроенная функция, которая дает вам адрес переменной.
Для начала нужно понять "почему именно эта проблема происходит?"
Адрес списка, присутствующего в обоих словах для ключа «а», указывает на то же место.
Поэтому, когда вы меняете значение списка в my_dict, список в my_copy также изменяется.
Решение для структуры данных, упомянутых в вопросе:
Или вы можете использовать Deepcopy, как указано выше.
источник
value[:]
. Решение было для конкретной структуры данных, упомянутой в вопросе, а не универсальным решением.Python 3.x
из копии импортировать Deepcopy
Без глубокого копирования я не могу удалить словарь имени хоста из словаря моего домена.
Без глубокой копии я получаю следующую ошибку:
... когда я пытаюсь удалить нужный элемент из моего словаря внутри другого словаря.
домен является объектом словаря
Пример вывода: [orginal] domains = {'localdomain': {'localhost': {'all': '4000'}}}
[новые] домены = {'localdomain': {}}}
Так что здесь происходит, я перебираю копию словаря, а не сам словарь. С помощью этого метода вы можете удалять элементы по мере необходимости.
источник
Я люблю и многому научился у Лассе В. Карлсена. Я изменил его в следующем примере, который хорошо показывает разницу между мелкими копиями словаря и глубокими копиями:
Теперь, если вы измените
и делай
ты получаешь
источник
Более простое (на мой взгляд) решение - создать новый словарь и обновить его содержимым старого:
Проблема с этим подходом в том, что он может быть недостаточно глубоким. то есть не рекурсивно глубоко. достаточно для простых объектов, но не для вложенных словарей. Вот пример, где это может быть недостаточно глубоко:
Используя Deepcopy (), я могу исключить полумелое поведение, но я думаю, что нужно решить, какой подход подходит для вашего приложения. В большинстве случаев вам может быть все равно, но следует помнить о возможных подводных камнях ... последний пример:
источник
my_dict.copy()
!