Iterando Dicionários Usando Loops 'For'
d = {'x': 1, 'y': 2, 'z': 3}
for key in d:
...
Como o Python reconhece que precisa apenas ler a chave do dicionário? Key é uma palavra especial em Python? Ou é simplesmente uma variável?
Não são apenas for
loops. A palavra importante aqui é "iterando".
Um dicionário é um mapeamento de chaves para valores:
d = {'x': 1, 'y': 2, 'z': 3}
Sempre que iteramos sobre ele, iteramos sobre as chaves. O nome da variável key
é apenas para ser descritivo - e é bastante adequado para esse propósito.
Isso acontece na compreensão de uma lista:
>>> [k for k in d]
['x', 'y', 'z']
Isso acontece quando passamos o dicionário para a lista (ou qualquer outro objeto de tipo de coleção):
>>> list(d)
['x', 'y', 'z']
A maneira como o Python itera é, em um contexto em que precisa, chama o __iter__
método do objeto (neste caso, o dicionário) que retorna um iterador (neste caso, um objeto keyiterator):
>>> d.__iter__()
<dict_keyiterator object at 0x7fb1747bee08>
Nós não devemos usar esses métodos especiais, em vez disso, use a respectiva função interna para chamá-la iter
:
>>> key_iterator = iter(d)
>>> key_iterator
<dict_keyiterator object at 0x7fb172fa9188>
Os iteradores têm um __next__
método - mas nós o chamamos com a função embutida next
:
>>> next(key_iterator)
'x'
>>> next(key_iterator)
'y'
>>> next(key_iterator)
'z'
>>> next(key_iterator)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
Quando um iterador está esgotado, ele aumenta StopIteration
. É assim que o Python sabe sair de um for
loop, de uma compreensão de lista, de uma expressão geradora ou de qualquer outro contexto iterativo. StopIteration
Quando um iterador aumenta, ele sempre será aumentado - se você quiser iterar novamente, precisará de um novo.
>>> list(key_iterator)
[]
>>> new_key_iterator = iter(d)
>>> list(new_key_iterator)
['x', 'y', 'z']
Voltando aos ditados
Já vimos ditados interagindo em muitos contextos. O que vimos é que sempre que iteramos sobre um ditado, obtemos as chaves. De volta ao exemplo original:
d = {'x': 1, 'y': 2, 'z': 3}
for key in d:
Se mudarmos o nome da variável, ainda obteremos as chaves. Vamos tentar:
>>> for each_key in d:
... print(each_key, '=>', d[each_key])
...
x => 1
y => 2
z => 3
Se queremos iterar sobre os valores, precisamos usar o .values
método dict, ou para os dois juntos .items
:
>>> list(d.values())
[1, 2, 3]
>>> list(d.items())
[('x', 1), ('y', 2), ('z', 3)]
No exemplo dado, seria mais eficiente iterar sobre os itens como este:
for a_key, corresponding_value in d.items():
print(a_key, corresponding_value)
Mas, para fins acadêmicos, o exemplo da pergunta é ótimo.