Ao ler a documentação dict.copy()
, ele diz que faz uma cópia superficial do dicionário. O mesmo vale para o livro que estou seguindo (Beazley's Python Reference), que diz:
O método m.copy () faz uma cópia superficial dos itens contidos em um objeto de mapeamento e os coloca em um novo objeto de mapeamento.
Considere isto:
>>> original = dict(a=1, b=2)
>>> new = original.copy()
>>> new.update({'c': 3})
>>> original
{'a': 1, 'b': 2}
>>> new
{'a': 1, 'c': 3, 'b': 2}
Portanto, presumi que isso atualizaria o valor de original
(e adicionaria 'c': 3) também porque eu estava fazendo uma cópia superficial. Como se você fizer isso para uma lista:
>>> original = [1, 2, 3]
>>> new = original
>>> new.append(4)
>>> new, original
([1, 2, 3, 4], [1, 2, 3, 4])
Isso funciona conforme o esperado.
Como as duas cópias são rasas, por que dict.copy()
isso não funciona como eu esperava? Ou meu entendimento de cópia superficial e profunda é falha?
python
dictionary
copy
user225312
fonte
fonte
Respostas:
Por "cópia superficial", significa que o conteúdo do dicionário não é copiado por valor, mas apenas criando uma nova referência.
Por outro lado, uma cópia profunda copiará todo o conteúdo por valor.
Assim:
b = a
: Atribuição de referência, marcaa
eb
aponta para o mesmo objeto.b = a.copy()
: Cópia rasaa
eb
se tornará dois objetos isolados, mas seu conteúdo ainda compartilha a mesma referênciab = copy.deepcopy(a)
: Cópia profunda,a
eb
a estrutura e o conteúdo ficam completamente isolados.fonte
L
novamenteb
. Fazer isso simplificaria o exemplo.b[1][0] = 5
. Seb
for uma cópia superficial, você acabou de mudara[1][0]
.Não se trata de cópia profunda ou superficial, nada do que você está fazendo é cópia profunda.
Aqui:
você está criando uma nova referência à lista / ditado referenciado pelo original.
enquanto aqui:
você está criando uma nova lista / ditado que é preenchido com uma cópia das referências de objetos contidas no contêiner original.
fonte
Veja este exemplo:
Agora vamos alterar um valor no nível 'raso' (primeiro):
Agora vamos alterar um valor um nível mais profundo:
fonte
no change in original, since ['a'] is an immutable integer
Este. Na verdade, responde à pergunta.Adicionando à resposta do kennytm. Quando você faz uma cópia superficial parent.copy () um novo dicionário é criado com as mesmas chaves, mas os valores não são copiados são referenced.If você adicionar um novo valor para parent_copy ele não vai efeito pai porque parent_copy é um novo dicionário sem referência.
O valor de hash (id) do pai [1] , parent_copy [1] é idêntico, o que implica [1,2,3] do pai [1] e do parent_copy [1] armazenados no id 140690938288400.
Mas o hash do pai e o parent_copy são diferentes, o que implica que eles são dicionários diferentes e parent_copy é um novo dicionário que tem valores de referência aos valores do pai
fonte
"novo" e "original" são ditados diferentes, é por isso que você pode atualizar apenas um deles. Os itens são copiados superficialmente, não o ditado em si.
fonte
O conteúdo é copiado superficialmente.
Portanto, se o original
dict
contiver umlist
ou outrodictionary
, modificá-los no original ou em sua cópia superficial os modificará (olist
ou odict
) no outro.fonte
Na sua segunda parte, você deve usar
new = original.copy()
.copy
e=
são coisas diferentes.fonte