python: anexando um dicionário a uma lista - vejo um ponteiro como o comportamento

88

Tentei o seguinte no interpretador python:

>>>
>>> a = []
>>> b = {1:'one'}
>>> a.append(b)
>>> a
[{1: 'one'}]
>>> b[1] = 'ONE'
>>> a
[{1: 'ONE'}]
>>>

Aqui, após anexar o dicionário 'b' à lista 'a', estou alterando o valor correspondente à chave 1 no dicionário 'a'. De alguma forma, essa mudança também se reflete na lista. Quando acrescento um dicionário a uma lista, não estou apenas acrescentando o valor do dicionário? Parece que acrescentei um ponteiro ao dicionário à lista e, portanto, as alterações no dicionário estão sendo refletidas na lista também.

Não quero que a mudança seja refletida na lista. Como eu faço isso?

Obrigado pelo seu tempo!

neo29
fonte
Chekhov Não é o dicionário 'b' , é o dicionário b ou o dicionário do nome 'b' . A propósito, você escreveu com erro: "Estou mudando o valor correspondente à chave 1 no dicionário 'a'" Não, no dicionário b. Quanto ao seu espanto: uma lista não contém valores, ela contém objetos, pois tudo é objeto em Python. Ou, mais exatamente, uma lista contém referências aos objetos.
eyquem,
Chekhov Você também deve ver esta pergunta: ( stackoverflow.com/questions/5242933/… )
eyquem
@eyquem obrigado pelo seu comentário. Eu estava postando isso com pressa. Me desculpe.
neo29,
Chekhov Não foi uma censura, foi apenas uma informação. A propósito, se minha resposta for de alguma forma útil, ela pode ser votada a favor. Além disso, você pode escolher "aceitar" uma resposta entre as respostas, clicando na faixa em forma de divisa sob o contador de pontos à esquerda de uma resposta, isso vai ganhar 25 pontos. Ou você pode escolher não aceitar nenhuma pergunta.
eyquem de

Respostas:

145

Você está correto ao dizer que sua lista contém uma referência ao dicionário original.

a.append(b.copy()) deve fazer o truque.

Tenha em mente que esta é uma cópia superficial. Uma alternativa é usar copy.deepcopy(b), o que faz uma cópia profunda.

NPE
fonte
6
impressionante! Fiquei bloqueado por muito tempo nisso
Yasin
2
isso estava explodindo minha mente por cerca de meia hora, até que desisti e decidi verificar a pilha.
FlyingZebra1
35

Também com dict

a = []
b = {1:'one'}

a.append(dict(b))
print a
b[1]='iuqsdgf'
print a

resultado

[{1: 'one'}]
[{1: 'one'}]
eyquem
fonte
Não tenho certeza se é rápido o suficiente como copy (), mas parece ser mais rápido que deepcopy (). Talvez com o esquema de dicionário complicado ele fique próximo de deepcopy () porque dict () cria um novo dicionário.
selotec