it-swarm-pt.tech

Iterando sobre dicionários usando loops 'for'

Estou um pouco confuso com o seguinte código:

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:
    print key, 'corresponds to', d[key]

O que eu não entendo é a porção key. Como o Python reconhece que precisa apenas ler a chave do dicionário? key é um Word especial em Python? Ou é simplesmente uma variável?

2665
TopChef

key é apenas um nome de variável.

for key in d:

irá simplesmente percorrer as teclas no dicionário, em vez das chaves e valores. Para repetir a chave e o valor, você pode usar o seguinte:

Para Python 2.x:

for key, value in d.iteritems():

Para o Python 3.x:

for key, value in d.items():

Para testar você mesmo, altere a palavra key para poop.

Para o Python 3.x, iteritems() foi substituído por simplesmente items(), que retorna uma visão do tipo conjunto, respaldada pelo dict, como iteritems(), mas ainda melhor. Isso também está disponível em 2.7 como viewitems().

A operação items() funcionará tanto para 2 como para 3, mas em 2 retornará uma lista dos pares (key, value) do dicionário, o que não refletirá mudanças no dict que ocorrem após a chamada items(). Se você quiser o comportamento 2.x em 3.x, você pode chamar list(d.items()).

4718
sberry

Não é que a chave seja um Word especial, mas os dicionários implementam o protocolo do iterador. Você poderia fazer isso em sua turma, por exemplo veja esta questão como construir os iteradores de classes.

No caso de dicionários, é implementado no nível C. Os detalhes estão disponíveis em PEP 234 . Em particular, a seção intitulada "Dicionário Iteradores":

  • Os dicionários implementam um slot tp_iter que retorna um iterador eficiente que itera sobre as chaves do dicionário. [...] isso significa que podemos escrever

    for k in dict: ...
    

    que é equivalente a, mas muito mais rápido que

    for k in dict.keys(): ...
    

    contanto que a restrição de modificações no dicionário (seja pelo loop ou por outro thread) não seja violada.

  • Adicione métodos a dicionários que retornam diferentes tipos de iteradores explicitamente:

    for key in dict.iterkeys(): ...
    
    for value in dict.itervalues(): ...
    
    for key, value in dict.iteritems(): ...
    

    Isso significa que for x in dict é uma abreviação para for x in dict.iterkeys().

No Python 3, dict.iterkeys(), dict.itervalues() e dict.iteritems() não são mais suportadas. Use dict.keys(), dict.values() e dict.items().

384
ars

A iteração de dict é iterada por meio de suas chaves sem nenhuma ordem específica, como você pode ver aqui:

Edit: (Isto é não é mais o caso em Python3.6, mas note que é não garantido behavior yet)

>>> d = {'x': 1, 'y': 2, 'z': 3} 
>>> list(d)
['y', 'x', 'z']
>>> d.keys()
['y', 'x', 'z']

Para o seu exemplo, é melhor usar dict.items():

>>> d.items()
[('y', 2), ('x', 1), ('z', 3)]

Isso te dá uma lista de tuplas. Quando você faz um loop sobre eles assim, cada Tuple é descompactado em k e v automaticamente:

for k,v in d.items():
    print(k, 'corresponds to', v)

Usando k e v como nomes de variáveis ​​quando o loop sobre um dict é bastante comum se o corpo do loop tiver apenas algumas linhas. Para loops mais complicados, pode ser uma boa ideia usar nomes mais descritivos:

for letter, number in d.items():
    print(letter, 'corresponds to', number)

É uma boa ideia adquirir o hábito de usar strings de formato:

for letter, number in d.items():
    print('{0} corresponds to {1}'.format(letter, number))
181
John La Rooy

key é simplesmente uma variável.

Para Python2.X :

d = {'x': 1, 'y': 2, 'z': 3} 
for my_var in d:
    print my_var, 'corresponds to', d[my_var]

... ou melhor,

d = {'x': 1, 'y': 2, 'z': 3} 
for the_key, the_value in d.iteritems():
    print the_key, 'corresponds to', the_value

Para Python3.X :

d = {'x': 1, 'y': 2, 'z': 3} 
for the_key, the_value in d.items():
    print(the_key, 'corresponds to', the_value)
71
ssoler

Quando você faz uma iteração através de dicionários usando a sintaxe for .. in .., ele sempre percorre as teclas (os valores são acessíveis usando dictionary[key]).

Para iterar sobre pares de valores-chave, use for k,v in s.iteritems().

49
Alexander Gessler

Este é um idioma de loop muito comum. in é um operador. Para quando usar for key in dict e quando deve ser for key in dict.keys() veja artigo de David Goodger Idiomatic Python .

26
chryss

Você pode usar isto:

for key,val in d.items():
    print key, 'is the key for ', val
16
A H M Forhadul Islam

Eu tenho um caso de uso onde eu tenho que iterar através do dict para obter a chave, par de valores, também o índice indicando onde estou. É assim que eu faço:

d = {'x': 1, 'y': 2, 'z': 3} 
for i, (key, value) in enumerate(d.items()):
   print(i, key, value)

Note que os parênteses em torno da chave, o valor é importante, sem os parênteses, você obtém um valor ValueError "não é suficiente para descompactar".

12
jdhao

seja qual for, hoje, tanto o python 2.6 e 2.7, quanto o 3.x, na minha caixa funcionam bem com items():

z = {0: 'a', 1: 'b'}
for k, v in z.items(): print(v, k)
12
象嘉道

Iterando sobre 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? A chave é um Word especial em Python? Ou é simplesmente uma variável?

Não são apenas loops for. A palavra importante aqui é "iterar".

Um dicionário é um mapeamento de chaves para valores:

d = {'x': 1, 'y': 2, 'z': 3} 

Sempre que fazemos uma iteração, iteramos as teclas. O nome da variável key destina-se apenas a ser descritivo - e é bastante adequado para o propósito.

Isso acontece em uma compreensão da lista:

>>> [k for k in d]
['x', 'y', 'z']

Isso acontece quando passamos o dicionário para listar (ou qualquer outro objeto de tipo de coleção):

>>> list(d)
['x', 'y', 'z']

A maneira que o Python é iterado é, em um contexto onde ele precisa, ele chama o método __iter__ 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á-lo, iter:

>>> key_iterator = iter(d)
>>> key_iterator
<dict_keyiterator object at 0x7fb172fa9188>

Os iteradores possuem um método __next__ - mas nós o chamamos com a função builtin, 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 gera StopIteration. É assim que o Python sabe como sair de um loop for, ou uma compreensão de lista, ou uma expressão de gerador, ou qualquer outro contexto iterativo. Uma vez que um iterador aumente StopIteration, ele sempre aumentará - 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 ditos

Nós vimos ditadores interagindo em muitos contextos. O que nós vimos é que a qualquer momento que fazemos uma iteração, recebemos 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 assim obteremos as chaves. Vamos tentar:

>>> for each_key in d:
...     print(each_key, '=>', d[each_key])
... 
x => 1
y => 2
z => 3

Se quisermos fazer uma iteração sobre os valores, precisamos usar o método .values de ditos, ou ambos juntos, .items:

>>> list(d.values())
[1, 2, 3]
>>> list(d.items())
[('x', 1), ('y', 2), ('z', 3)]

No exemplo dado, seria mais eficiente fazer uma iteração 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 é bom.

11
Aaron Hall

Você pode verificar a implementação do dicttype do CPython no GitHub. Esta é a assinatura do método que implementa o dict iterator:

_PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey,
             PyObject **pvalue, Py_hash_t *phash)

CPython dictobject.c

7
abc

Para iterar as teclas, é mais lento, mas é melhor usar my_dict.keys(). Se você tentou fazer algo assim:

for key in my_dict:
    my_dict[key+"-1"] = my_dict[key]-1

ele criaria um erro de tempo de execução porque você está alterando as chaves enquanto o programa está em execução. Se você está absolutamente determinado a reduzir o tempo, use o método for key in my_dict, mas você foi avisado;).

2
Neil Chowdhury o_O

Para key em my_dict, na verdade, é igual a key em my_dict.keys (). Então, se você quiser obter valores de dict você pode tentar dois métodos.

1:

for value in my_dict.values():
    print(value)

Dois:

for key in my_dict:
    print(my_dict[key])
1
Amaan Durrani

Sugestão de impressão para valores longos
Se você tiver strings longas nos valores, aqui está uma maneira rápida de imprimir isso em um formato (mais?) Legível:
for key, value in my_dictionary.iteritems(): print(key) print("---------") print(value) print("\n")

0
Joseph True