Fala, pessoal! Tudo tranquilo?
Neste artigo irei compartilhar com vocês uma dica que aprendi para criar um dict ou dicionário, a partir de outros dicts em Python. Como já é de costume da linguagem, nós podemos fazer isso de várias maneiras diferentes.
Vamos supor que temos os seguintes dicionários:
dict_1 = { 'a': 1, 'b': 2, } dict_2 = { 'b': 3, 'c': 4, }
Como exemplo, vamos criar um novo dicionário chamado n_dict com os valores dos dois dicts acima. Uma abordagem bem conhecida é utilizar o método update.
n_dict = {} n_dcit.update(dict_1) n_dcit.update(dict_2)
Assim, temos que n_dict será:
n_dict = { 'a': 1, 'b': 3, 'c': 4, }
Este método funciona bem, porém, temos de chamar o método update para cada dict que desejamos “inserir” em n_dict. Não seria interessante se fosse possível passar todos os dicts necessários já na inicialização de n_dict?
O Python 3 introduziu uma maneira bem interessante de se fazer isso, utilizando os operadores **.
n_dict = { **dict_1, **dict_2, }
Assim, de maneira semelhante ao exemplo anterior, temos que n_dict será:
print(n_dict['a']) # Saida: 1 print(n_dict['b']) # Saida: 3 print(n_dict['c']) # Saida: 4
Cópia de dicts dentro de dicts
Devemos ter um cuidado extra quando utilizamos o precedimento de inicialização acima. Apenas os valores do primeiro nível serão realmente duplicados no novo dicionário. Como exemplo, vamos alterar uma chave presente em ambos os dicts e verificar se as mesmas possuem o mesmo valor:
dict_1['a'] = 10 n_dict['a'] = 11 print(dict_1['a']) # Saida: 10 print(n_dict['a']) # Saida: 11
Porém, isso muda quando um dos valores de dict_1 for uma list, outro dict ou algum objeto complexo. Por exemplo:
dict_3 = { 'a': 1, 'b': 2, 'c': { 'd': 5, } }
E agora vamos criar um novo dict a partir desse:
n_dict = { **dict_3, }
Como no exemplo anterior, podemos imaginar que foi realizada uma cópia de todos os elementos de dict_3, porém, isso não é totalmente verdade. O que realmente aconteceu é que foi feita uma cópia superficial dos valores de dict_3, ou seja, apenas os valores de primeiro nível foram duplicados. Observe o que acontece quando alteramos o valor do dict presente na chave c:
n_dict['c']['d'] = 11 print(n_dict['c']['d']) # Saida: 11 print(dict_3['c']['d']) # Saida: 11 (valor anterior era 5)
No caso da chave c, ela contém uma referência para outra estrutura de dados (um dict, no caso). Quando alteramos algum valor de dict_3[‘c’], isso reflete em todos os dict que foram inicializados com dict_3. Em outras palavras, deve-se ter cuidado ao inicializar um dict a partir de outros dicts quando os mesmos possuírem valores complexos, como: list, dict ou outros objetos (os atributos deste objeto não serão duplicados).
De modo a contornar este inconveniente, podemos utilizar o método deepcopy da lib nativa copy. Agora, ao inicializarmos n_dict:
import copy dict_3 = { 'a': 1, 'b': 2, 'c': { 'd': 5, } } n_dict = copy.deepcopy(dict_3)
O método deepcopy realiza uma cópia recursiva de cada elemento de dict_3, resolvendo nosso problema. Veja mais um exemplo:
n_dict['c']['d'] = 11 print(n_dict['c']['d']) # Saida: 11 print(dict_3['c']['d']) # Saida: 5 (valor não foi alterado)
Para mais detalhes e outros exemplos, deem uma olhada neste artigo do fórum da Python Brasil aqui.
É isso, pessoal. Espero que essa dica seja útil para vocês.
Até o próximo artigo!