Eu gostaria de fazer uma cópia profunda de um dict
em python. Infelizmente, o .deepcopy()
método não existe para o dict
. Como faço isso?
>>> 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
A última linha deve ser 3
.
Gostaria que as modificações my_dict
não afetassem o instantâneo my_copy
.
Como faço isso? A solução deve ser compatível com o Python 3.x.
python
python-3.x
Olivier Grégoire
fonte
fonte
Respostas:
E se:
Python 2 ou 3:
fonte
copy.deepcopy
thread não é seguro. Aprendi isso da maneira mais difícil. Por outro lado, dependendo do seu caso de uso,json.loads(json.dumps(d))
é seguro para threads e funciona bem.json.loads
não resolve o problema em todos os casos de uso em que osdict
atributos python não são serializáveis em JSON. Pode ajudar aqueles que estão lidando apenas com estruturas de dados simples, de uma API, por exemplo, mas não acho que seja uma solução suficiente para responder completamente à pergunta do OP.dict.copy () é uma função de cópia superficial para a
identificação do dicionário é a função interna que fornece o endereço da variável
Primeiro você precisa entender "por que esse problema específico está acontecendo?"
O endereço da lista presente nos dois ditados da chave 'a' está apontando para o mesmo local.
Portanto, quando você altera o valor da lista em my_dict, a lista em my_copy também muda.
Solução para estrutura de dados mencionada na pergunta:
Ou você pode usar a cópia em profundidade, conforme mencionado acima.
fonte
value[:]
. A solução foi para a estrutura de dados específica mencionada na pergunta e não para uma solução universal.Python 3.x
da cópia importada
Sem a cópia em profundidade, não consigo remover o dicionário de nome de host do dicionário de domínio.
Sem a cópia em profundidade, recebo o seguinte erro:
... quando tento remover o elemento desejado do meu dicionário dentro de outro dicionário.
domínio é um objeto de dicionário
Exemplo de saída: [orginal] domínios = {'localdomain': {'localhost': {'all': '4000'}}}
[new] domínios = {'localdomain': {}}}
Então, o que está acontecendo aqui é que estou repetindo uma cópia de um dicionário, em vez de repetir o próprio dicionário. Com esse método, você pode remover elementos conforme necessário.
fonte
Gosto e aprendi muito com Lasse V. Karlsen. Eu o modifiquei no exemplo a seguir, que destaca muito bem a diferença entre cópias de dicionário rasas e cópias profundas:
Agora, se você mudar
e fazer
você recebe
fonte
Uma solução mais simples (na minha opinião) é criar um novo dicionário e atualizá-lo com o conteúdo do antigo:
O problema dessa abordagem é que ela pode não ser "profunda o suficiente". isto é, não é recursivamente profundo. bom o suficiente para objetos simples, mas não para dicionários aninhados. Aqui está um exemplo em que pode não ser suficientemente profundo:
Usando Deepcopy (), posso eliminar o comportamento semi-superficial, mas acho que é preciso decidir qual abordagem é adequada para o seu aplicativo. Na maioria dos casos, você pode não se importar, mas deve estar ciente das possíveis armadilhas ... exemplo final:
fonte
my_dict.copy()
!