Skip to content

Commit df64dc8

Browse files
committed
Post sobre criacao de dicts em Python
1 parent 4d6a1f5 commit df64dc8

File tree

1 file changed

+161
-0
lines changed

1 file changed

+161
-0
lines changed
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
Title: Criando dicts a partir de outros dicts
2+
Slug: crie_dict-a-partir-de-outros-dicts
3+
Date: 2019-10-01 20:20:29
4+
Category: Python
5+
Tags: Python, Dict
6+
Author: Michell Stuttgart
7+
Email: michellstut@gmail.com
8+
Github: mstuttgart
9+
Linkedin: mstuttgart
10+
Site: https://mstuttgart.github.io
11+
Summary: Crie dicts a partir de outros dicts
12+
13+
Neste tutorial, será abordado o processo de criação de um *dict* ou dicionário, a partir de um ou mais *dicts* em Python.
14+
15+
Como já é de costume da linguagem, isso pode ser feito de várias maneiras diferentes.
16+
17+
## Abordagem inicial
18+
19+
Pra começar, vamos supor que temos os seguintes dicionários:
20+
21+
```python
22+
dict_1 = {
23+
'a': 1,
24+
'b': 2,
25+
}
26+
27+
dict_2 = {
28+
'b': 3,
29+
'c': 4,
30+
}
31+
```
32+
33+
Como exemplo, vamos criar um novo dicionário chamado **new_dict** com os valores de **dict_1** e **dict_2** logo acima. Uma abordagem bem conhecida é utilizar o método *update*.
34+
35+
```python
36+
new_dict = {}
37+
38+
new_dcit.update(dict_1)
39+
new_dcit.update(dict_2)
40+
```
41+
42+
Assim, temos que **new_dict** será:
43+
44+
```python
45+
>> print(new_dict)
46+
{
47+
'a': 1,
48+
'b': 3,
49+
'c': 4,
50+
}
51+
```
52+
53+
Este método funciona bem, porém temos de chamar o método *update* para cada *dict* que desejamos mesclar em **new_dict**. Não seria interessante se fosse possível passar todos os *dicts* necessários já na inicialização de **new_dict**?
54+
55+
### Novidades do Python 3
56+
57+
O Python 3 introduziu uma maneira bem interessante de se fazer isso, utilizando os operadores `**`.
58+
59+
```python
60+
new_dict = {
61+
**dict_1,
62+
**dict_2,
63+
}
64+
65+
```
66+
67+
Assim, de maneira semelhante ao exemplo anterior, temos que **new_dict** será :
68+
69+
```python
70+
>> print(new_dict['a'])
71+
1
72+
>> print(new_dict['b'])
73+
3
74+
>> print(new_dict['c'])
75+
4
76+
```
77+
78+
## Cópia real de *dicts*
79+
80+
Ao utilizamos o procedimento de inicialização acima, devemos tomar conseiderar alguns fatores. 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:
81+
82+
```python
83+
>> dict_1['a'] = 10
84+
>> new_dict['a'] = 11
85+
>> print(dict_1['a'])
86+
10
87+
>> print(new_dict['a'])
88+
11
89+
```
90+
91+
Porém isso muda quando um dos valores de **dict_1** for uma *list*, outro *dict* ou algum objeto complexo. Por exemplo:
92+
93+
```python
94+
dict_3 = {
95+
'a': 1,
96+
'b': 2,
97+
'c': {
98+
'd': 5,
99+
}
100+
}
101+
```
102+
103+
e agora, vamos criar um novo *dict* a partir desse:
104+
105+
```python
106+
new_dict = {
107+
**dict_3,
108+
}
109+
110+
```
111+
112+
Como no exemplo anterior, podemos imaginar que foi realizado 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**.
113+
114+
```python
115+
>> new_dict['c']['d'] = 11
116+
>> print(new_dict['c']['d'])
117+
11
118+
>> print(dict_3['c']['d'])
119+
11
120+
# valor anterior era 5
121+
122+
```
123+
124+
No caso da chave **c**, ela contem 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).
125+
126+
De modo a contornar este inconveniente, podemos utilizar o método *deepcopy* da *lib* nativa [copy](https://docs.python.org/2/library/copy.html). Agora, ao inicializarmos **new_dict**:
127+
128+
```python
129+
import copy
130+
131+
dict_3 = {
132+
'a': 1,
133+
'b': 2,
134+
'c': {
135+
'd': 5,
136+
}
137+
}
138+
139+
new_dict = copy.deepcopy(dict_3)
140+
```
141+
142+
O método *deepcopy* realiza uma cópia recursiva de cada elemento de **dict_3**, resolvendo nosso problema. Veja mais um exemplo:
143+
144+
```python
145+
>> new_dict['c']['d'] = 11
146+
>> print(new_dict['c']['d'])
147+
11
148+
>> print(dict_3['c']['d'])
149+
5
150+
# valor não foi alterado
151+
```
152+
153+
## Conclusão
154+
155+
Este artigo tenta demonstrar de maneira simples a criação de *dicts*, utilizando os diversos recursos que a linguagem oferece bem como os prós e contras de cada abordagem.
156+
157+
## Referências
158+
159+
Para mais detalhes e outros exemplos, deem uma olhada neste *post* do forum da Python Brasil [aqui](https://groups.google.com/forum/#!topic/python-brasil/OhUqYQ32M7E).
160+
161+
É isso pessoal. Obrigado por ler!

0 commit comments

Comments
 (0)