
Passo 1 de 8
Dois nomes podem apontar para a mesma coleção
Reconheça quando dois nomes dão acesso à mesma lista ou ao mesmo dicionário e preveja o que acontece ao alterar essa coleção.
Trilha de aprendizado · Nível 3 · Tutorial 9
Prever quando uma alteração será visível por outros nomes ou coleções e reconhecer os limites das cópias rasas em estruturas aninhadas.
Dois nomes podem apontar para a mesma coleção
Reconheça quando dois nomes dão acesso à mesma lista ou ao mesmo dicionário e preveja o que acontece ao alterar essa coleção. 2 min
Reatribuir um nome não é modificar o objeto
Distinga mudanças no objeto de mudanças na referência de um nome e preveja o que outro nome verá. 3 min
Mesmo conteúdo não significa mesmo objeto
Compare listas com == e is para distinguir conteúdo igual de referências ao mesmo objeto. 2 min
Criar cópias rasas de listas e dicionários
Use copy() para criar outro contêiner e alterar suas posições ou chaves sem mudar o contêiner original. 3 min
Entender o que continua compartilhado na cópia
Preveja quando uma alteração na cópia rasa alcança o original e quando fica apenas no contêiner copiado. 4 min
Construir listas internas independentes
Reconheça referências repetidas e construa uma nova lista interna a cada passagem do laço. 3 min
Uma tupla não congela seus objetos internos
Distinguir a substituição de uma posição da tupla da alteração de uma lista guardada nessa posição. 2 min
Aplicar e revisar o controle de referências
Analise um quadro de tarefas, corrija listas internas compartilhadas e justifique o que uma cópia rasa mantém em comum. 4 min

Passo 1 de 8
Reconheça quando dois nomes dão acesso à mesma lista ou ao mesmo dicionário e preveja o que acontece ao alterar essa coleção.
O nome usado no código e a lista são coisas diferentes: o nome é uma forma de acessar o objeto. Dizemos que ele guarda uma referência à lista.
Ao executar outra = tarefas, você faz outra apontar para a mesma lista que tarefas. Essa atribuição não cria uma cópia.
tarefas = ["ler"]
outra = tarefas![Os nomes tarefas e outra têm setas que chegam à mesma lista, cujo conteúdo é ['ler']. Há dois nomes, mas apenas uma lista.](https://cursa-json-routes.s3.amazonaws.com/learning-paths/pt/python/b730454e0225/level-03/tutorial-09/step-01/screen-01/item-03.webp)
As setas representam referências. Alterar essa lista será visível pelos dois nomes.
Leia o código e preveja as duas linhas exibidas.
tarefas = ["ler"]
outra = tarefas
outra.append("revisar")
print(tarefas)
print(outra)Qual será a saída, na ordem dos prints?
Atribuir um dicionário existente a outro nome também compartilha a referência. Neste exemplo, a atualização feita por painel pode ser consultada por pedido.
pedido = {"status": "aberto"}
painel = pedido
painel["status"] = "pronto"
print(pedido)
print(painel)Exemplo
As duas linhas exibem {'status': 'pronto'}. Há um só dicionário, com dois nomes dando acesso a ele.
Agora represente este trecho com um diagrama.
a = [7]
b = aQual diagrama representa o resultado dessas duas linhas?

Passo 2 de 8
Distinga mudanças no objeto de mudanças na referência de um nome e preveja o que outro nome verá.
Quando dois nomes apontam para uma lista, alterar essa lista afeta o que ambos consultam. Essa alteração do próprio objeto se chama mutação. Tanto append quanto a atribuição a uma posição, como a[0] = 9, modificam a lista.
a = [1, 2]
b = a
a.append(3)
a[0] = 9
print(a) # [9, 2, 3]
print(b) # [9, 2, 3]![Três estados: a e b apontam para uma única lista [1, 2]; depois de append, essa lista contém [1, 2, 3]; depois da atribuição ao índice zero, contém [9, 2, 3]. As referências permanecem iguais.](https://cursa-json-routes.s3.amazonaws.com/learning-paths/pt/python/b730454e0225/level-03/tutorial-09/step-02/screen-01/item-03.webp)
O conteúdo muda; as duas setas continuam chegando à mesma lista.
No exemplo anterior, a[0] = 9 faz apenas o nome a passar a apontar para outra lista, deixando b com [1, 2, 3].
Já a = [9] faz o nome a apontar para uma nova lista. Isso é reatribuição: a lista anterior não é modificada, e b continua apontando para ela. A partir daí, alterar a nova lista por a não altera a lista de b.
a = [1, 2]
b = a
a = [9] # Reatribuição: muda o destino de a.
a.append(3) # Mutação: altera a nova lista.
print(a) # [9, 3]
print(b) # [1, 2]![Antes, a e b apontam para [1, 2]. Após a = [9], a aponta para uma nova lista [9], enquanto b permanece com [1, 2]. Após a.append(3), só a nova lista passa a conter [9, 3].](https://cursa-json-routes.s3.amazonaws.com/learning-paths/pt/python/b730454e0225/level-03/tutorial-09/step-02/screen-03/item-03.webp)
Reatribuir muda uma seta. A mutação seguinte altera o objeto no destino dessa seta.
Para cada operação do exercício, comece novamente com estas duas linhas. As operações são independentes, não uma sequência.
a = [1, 2]
b = aAssocie cada operação ao tipo de mudança e ao estado final de a e b.
Toque em um item e depois no par correspondente.

Passo 3 de 8
Compare listas com == e is para distinguir conteúdo igual de referências ao mesmo objeto.
Para listas, == pergunta: os conteúdos são iguais, na mesma ordem? Já is pergunta: é o mesmo objeto?
No exemplo, a e b apontam para uma única lista. A lista de c foi criada separadamente, embora tenha o mesmo conteúdo.
a = [10, 20]
b = a
c = [10, 20]
print(a == b) # True
print(a is b) # True
print(a == c) # True
print(a is c) # False![Os nomes a e b apontam para uma única lista [10, 20]. O nome c aponta para outra lista [10, 20], separada da primeira.](https://cursa-json-routes.s3.amazonaws.com/learning-paths/pt/python/b730454e0225/level-03/tutorial-09/step-03/screen-01/item-03.webp)
Conteúdos iguais podem estar em objetos distintos. As setas mostram quais nomes apontam para cada objeto.
Se a == c resulta em True, então a is c também precisa resultar em True.
Se você quer saber se duas listas têm os mesmos itens na mesma ordem, use ==. Não o substitua por is: isso mudaria a pergunta para identidade.
Exemplo
resposta = [2, 4]esperado = [2, 4]
resposta == esperado resulta em True: o conteúdo corresponde ao esperado.
resposta is esperado resulta em False: são duas listas criadas separadamente. Isso não significa que a resposta esteja errada.
Dica
Use is quando a pergunta for sobre compartilhamento: “Estes dois nomes apontam para a mesma lista?”
Leia o código e preveja os resultados antes de executá-lo.
a = [10, 20]
b = a
c = [10, 20]
b.append(30)
print(a == b)
print(a is b)
print(a == c)Quais são os três resultados, na ordem dos prints?

Passo 4 de 8
Use copy() para criar outro contêiner e alterar suas posições ou chaves sem mudar o contêiner original.
outro = original compartilha a lista existente. Já copia = original.copy() cria uma nova lista: inicialmente, o conteúdo é igual, mas a identidade é diferente.
A cópia é rasa: copia as referências dos elementos para um novo contêiner externo, sem duplicar os objetos recursivamente. Aqui, vamos alterar apenas esse nível externo.
Inclusões, substituições e remoções na cópia não alteram as posições da lista original.
original = [10, 20]
outro = original
copia = original.copy()
print(outro is original) # True
print(copia == original) # True
print(copia is original) # False
copia.append(30)
copia[0] = 99
copia.pop(1)
print(original) # [10, 20]
print(copia) # [99, 30]
Logo após copy(): duas listas distintas, apesar do conteúdo igual.
Complete com o nome do método, sem parênteses, para que append não altere tarefas:
tarefas = ["ler", "revisar"]
rascunho = tarefas.____()
rascunho.append("enviar")dicionario.copy() cria outro dicionário e preserva as referências aos valores. Assim como na lista, o conteúdo começa igual, mas o objeto externo é outro.
Você pode incluir uma chave, remover outra ou substituir um valor na cópia sem alterar essas associações no original.
Os valores deste exemplo são simples. Observe que todas as mudanças acontecem no dicionário rascunho.
estoque = {"lapis": 10, "canetas": 5}
rascunho = estoque.copy()
print(rascunho == estoque) # True
print(rascunho is estoque) # False
rascunho["lapis"] = 8
rascunho["borrachas"] = 3
del rascunho["canetas"]
print(estoque)
# {'lapis': 10, 'canetas': 5}
print(rascunho)
# {'lapis': 8, 'borrachas': 3}Use este trecho para responder às duas questões. A lacuna representa o nome de um método.
cadastro = {"nome": "Ana", "pontos": 10}
edicao = cadastro.____()
edicao["pontos"] = 15
del edicao["nome"]
print(cadastro)Qual método completa a lacuna para manter cadastro intacto? Digite sem parênteses.
Com a cópia criada corretamente, o que print(cadastro) mostra?

Passo 5 de 8
Preveja quando uma alteração na cópia rasa alcança o original e quando fica apenas no contêiner copiado.
A cópia rasa cria um contêiner externo novo, mas preserva as referências aos objetos internos. Assim, copia[0].append(...) alcança e modifica a mesma lista interna que original[0].
original = [["ler"]]
copia = original.copy()
print(original is copia) # False
print(original[0] is copia[0]) # True
copia[0].append("praticar")
print(original) # [['ler', 'praticar']]
print(copia) # [['ler', 'praticar']]
O append altera a lista interna compartilhada, não cria uma segunda lista interna.
original = [["ler"]]
copia = original.copy()
copia[0] = ["praticar"]
print(original)
print(copia)Quais são as duas saídas, na ordem?
No dicionário copiado, substituir o valor de uma chave afeta só a cópia. Já modificar uma lista que continua compartilhada afeta o que você vê pelos dois dicionários. Acompanhe as duas operações:
original = {"hoje": ["ler"], "amanha": ["revisar"]}
copia = original.copy()
copia["hoje"] = ["praticar"]
copia["amanha"].append("testar")
print(original)
# {'hoje': ['ler'], 'amanha': ['revisar', 'testar']}
print(copia)
# {'hoje': ['praticar'], 'amanha': ['revisar', 'testar']}Dica
copia["hoje"] = ... altera um vínculo no dicionário copiado. copia["amanha"].append(...) altera a lista alcançada por esse vínculo. Pergunte: quem mais aponta para o objeto que está sendo alterado?
Leia e preveja as saídas antes de executar. Se quiser conferir, use seu próprio Python.
quadro = {"tarefas": ["ler"]}
rascunho = quadro.copy()
rascunho["tarefas"].append("revisar")
rascunho["tarefas"] = ["praticar"]
print(quadro["tarefas"])
print(rascunho["tarefas"])Quais são as duas saídas? Explique por que a primeira alteração aparece em quadro, mas a segunda não.
Escreva pelo menos 30 caracteres (0/30).

Passo 6 de 8
Reconheça referências repetidas e construa uma nova lista interna a cada passagem do laço.
Em [[0, 0]] * 3, o * repete as referências aos elementos da lista externa. Como ela contém uma única lista interna, as três posições passam a apontar para essa mesma lista. Alterar uma célula fica visível pelos três caminhos.
linhas = [[0, 0]] * 3
print(linhas[0] is linhas[1]) # True
linhas[0][0] = 9
print(linhas) # [[9, 0], [9, 0], [9, 0]]![Uma lista externa tem três posições, de índices 0, 1 e 2. De cada posição sai uma seta para a mesma lista interna [9, 0].](https://cursa-json-routes.s3.amazonaws.com/learning-paths/pt/python/b730454e0225/level-03/tutorial-09/step-06/screen-01/item-03.webp)
O 9 não foi escrito em três listas: existe apenas uma lista interna, acessada por três posições.
Dica
Crie a lista externa vazia antes do laço. Dentro de cada iteração, crie uma nova lista interna com [0, 0] e adicione-a à externa com append. Assim, cada posição receberá uma lista diferente.
Ordene as etapas para construir três listas internas independentes.
Neste código, [0, 0] cria uma nova lista a cada passagem. O nome linha passa a apontar para ela, enquanto as listas anteriores continuam acessíveis pelas posições de linhas.
Execute este trecho no seu Python. Os comentários mostram os resultados esperados.
linhas = []
for numero in range(3):
linha = [0, 0]
linhas.append(linha)
print(linhas[0] is linhas[1]) # False
print(linhas[0] is linhas[2]) # False
print(linhas[1] is linhas[2]) # False
linhas[0][0] = 9
print(linhas) # [[9, 0], [0, 0], [0, 0]]linha = [0, 0]
linhas = []
for numero in range(3):
linhas.append(linha)
linhas[0][0] = 9
print(linhas) # [[9, 0], [9, 0], [9, 0]]Atenção
No segundo trecho, o append guarda três vezes a referência à mesma lista criada fora do laço. O que evita o compartilhamento é criar uma lista nova em cada iteração, não apenas trocar * por for.
No seu computador, use o trecho completo “Construção independente”. Troque apenas linhas[0][0] = 9 por linhas[1][1] = 7 e execute o código inteiro novamente. Relate os resultados das comparações com is, a lista final e por que a alteração ficou restrita a uma lista interna.
Escreva pelo menos 30 caracteres (0/30).

Passo 7 de 8
Distinguir a substituição de uma posição da tupla da alteração de uma lista guardada nessa posição.
A imutabilidade da tupla vale para suas posições: você não pode substituir as referências que elas guardam. Mas, se uma posição aponta para uma lista, essa lista continua mutável.
No exemplo, registro[1] dá acesso à lista. O append modifica essa lista, não a posição da tupla.
registro = ("Ana", ["Python"])
registro[1].append("SQL")
print(registro)
# ('Ana', ['Python', 'SQL'])![Antes e depois do append: a tupla registro mantém duas posições. A posição 0 aponta para Ana e a posição 1 aponta para a mesma lista, que passa de ['Python'] para ['Python', 'SQL'].](https://cursa-json-routes.s3.amazonaws.com/learning-paths/pt/python/b730454e0225/level-03/tutorial-09/step-07/screen-01/item-03.webp)
A seta da posição 1 não muda de destino. Só o conteúdo da lista muda.
No exemplo anterior, registro[1].append("SQL") substituiu a lista por outra na posição 1 da tupla.
Já uma atribuição a registro[1] tenta colocar outra referência nessa posição. A tupla não permite essa substituição, mesmo que o novo valor também seja uma lista.
Se executar este trecho no seu Python, ele será interrompido na segunda linha com um TypeError.
registro = ("Ana", ["Python"])
registro[1] = ["Python", "SQL"]
# TypeError: a tupla não permite atribuição a uma posição.Dica
Em registro[1] = ..., o alvo é uma posição da tupla. Em registro[1].append(...), o alvo é a lista alcançada por essa posição. O que importa é qual objeto a operação tenta modificar.
Considere pacote = ("cursos", ["Python", "SQL"]).
A: pacote[1].pop()
B: pacote[1] = []
Avalie cada operação separadamente, partindo da tupla original. Qual é permitida? Como fica o conteúdo de pacote depois dela? Explique por que isso não contradiz a imutabilidade da tupla.
Escreva pelo menos 30 caracteres (0/30).

Passo 8 de 8
Analise um quadro de tarefas, corrija listas internas compartilhadas e justifique o que uma cópia rasa mantém em comum.
Para trabalhar com um quadro de tarefas, escolha conforme a intenção:
atalho = quadro.rascunho = quadro.copy().
Logo após a cópia: atalho is quadro é True; rascunho is quadro é False; rascunho['hoje'] is quadro['hoje'] é True.
Dica
Reatribuir um nome muda sua seta. Substituir uma entrada muda a seta daquela entrada. Modificar uma lista muda o objeto alcançado pelas setas. Conteúdo igual (==) não prova identidade (is).
Leia o script sem executá-lo ainda. A intenção é ter um rascunho do quadro e duas colunas independentes.
quadro = {"hoje": ["ler"], "amanha": []}
atalho = quadro
rascunho = quadro.copy()
rascunho["hoje"].append("revisar")
rascunho["amanha"] = ["praticar"]
colunas = [[]] * 2
colunas[0].append("ler")
print(quadro)
print(rascunho)
print(atalho is quadro, rascunho is quadro)
print(colunas)Preveja as quatro linhas impressas. Explique por que “revisar” aparece no quadro original, “praticar” não aparece nele e “ler” aparece nas duas colunas.
Escreva pelo menos 30 caracteres (0/30).
No seu editor, substitua a construção de colunas por um laço que crie uma lista nova a cada passagem. Compare sua solução com a versão completa abaixo e execute-a com Python. O compartilhamento de hoje foi mantido de propósito: a correção é apenas das colunas.
quadro = {"hoje": ["ler"], "amanha": []}
atalho = quadro
rascunho = quadro.copy()
rascunho["hoje"].append("revisar")
rascunho["amanha"] = ["praticar"]
colunas = []
for numero in range(2):
coluna = []
colunas.append(coluna)
colunas[0].append("ler")
print(quadro)
print(rascunho)
print(atalho is quadro, rascunho is quadro)
print(colunas)
print(colunas[0] is colunas[1])
print(quadro["hoje"] is rascunho["hoje"])Relate o resultado de print(colunas) e das duas últimas comparações. Por que a correção isolou as colunas, mas não a lista hoje? Para substituir uma entrada sem substituir a do quadro original, você usaria atalho ou rascunho?
Escreva pelo menos 40 caracteres (0/40).
Resumo
Use estas perguntas para prever o efeito, em vez de confiar apenas na aparência dos valores.
Parabéns! Você concluiu: Controlar referências e cópias de coleções
Milhares de cursos online em vídeo, ebooks e áudiobooks.
Para testar seus conhecimentos no decorrer dos cursos online
Gerado diretamente na galeria de fotos do seu celular e enviado ao seu e-mail
Baixe nosso aplicativo pelo QR Code ou pelos links abaixo:.
+ de 10 milhões
de alunos
Certificado grátis e
válido em todo o Brasil
60 mil exercícios
gratuitos
4,8/5 classificação
nas lojas de apps
Cursos gratuitos em
vídeo, ebooks e audiobooks