kutombawewe.net

Iterare sui dizionari usando i cicli 'for'

Sono un po 'perplesso dal seguente codice:

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

Quello che non capisco è la porzione key. In che modo Python riconosce che è sufficiente leggere la chiave dal dizionario? key è una parola speciale in Python? O è semplicemente una variabile?

2665
TopChef

keyè solo un nome di variabile.

for key in d:

semplicemente passerà sopra i tasti nel dizionario, piuttosto che le chiavi e i valori. Per eseguire il loop su chiave e valore è possibile utilizzare quanto segue:

Per Python 2.x:

for key, value in d.iteritems():

Per Python 3.x:

for key, value in d.items():

Per testare da solo, cambia la parola keyin poopname__.

Per Python 3.x, iteritems() è stato sostituito con semplicemente items(), che restituisce una vista set-like supportata dal dict, come iteritems() ma ancora migliore. Questo è anche disponibile in 2.7 come viewitems().

L'operazione items() funzionerà sia per 2 che per 3, ma in 2 restituirà una lista delle coppie (key, value) del dizionario, che non rifletteranno le modifiche al dict che si verificano dopo la chiamata items(). Se si desidera il comportamento 2.x in 3.x, è possibile chiamare list(d.items()).

4718
sberry

Non è che la chiave sia una parola speciale, ma quei dizionari implementano il protocollo iteratore. Potresti farlo nella tua classe, ad es. vedere questa domanda per come costruire gli iteratori di classe.

Nel caso dei dizionari, è implementato a livello C. I dettagli sono disponibili in PEP 234 . In particolare, la sezione intitolata "Iterator dei dizionari":

  • I dizionari implementano uno slot tp_iter che restituisce un efficiente iteratore che itera sulle chiavi del dizionario. [...] Questo significa che possiamo scrivere

    for k in dict: ...
    

    che è equivalente a, ma molto più veloce di

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

    fino a quando la restrizione sulle modifiche al dizionario (sia dal loop o da un altro thread) non viene violata.

  • Aggiungi metodi ai dizionari che restituiscono diversi tipi di iteratori in modo esplicito:

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

    Ciò significa che for x in dict è una scorciatoia per for x in dict.iterkeys().

In Python 3, dict.iterkeys(), dict.itervalues() e dict.iteritems() non sono più supportati. Utilizzare invece dict.keys(), dict.values() e dict.items().

384
ars

L'iterazione su un dict scorre le sue chiavi in ​​nessun ordine particolare, come puoi vedere qui:

Modifica: (Questo è non è più il caso in Python3.6, ma nota che è non garantito comportamento ancora)

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

Per il tuo esempio, è meglio usare dict.items():

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

Questo ti dà una lista di tuple. Quando esegui il loop su di essi in questo modo, ciascuna Tupla viene decompressa in k e v automaticamente:

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

Usare k e v come nomi di variabili quando si esegue il ciclo su un dict è abbastanza comune se il corpo del ciclo è composto da poche righe. Per i loop più complicati può essere una buona idea usare nomi più descrittivi:

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

È una buona idea prendere l'abitudine di utilizzare le stringhe di formato:

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

key è semplicemente una variabile.

Per Python2.X :

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

... o meglio,

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

Per 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 si scorre i dizionari usando la sintassi for .. in ..-, itera sempre sulle chiavi (i valori sono accessibili usando dictionary[key]).

Per ripetere le coppie chiave-valore, utilizzare for k,v in s.iteritems().

49

Questo è un idioma di loop molto comune. in è un operatore. Per quando utilizzare for key in dict e quando deve essere for key in dict.keys() vedere Articolo di David Goodger Idiomatic Python .

26
chryss

Puoi usare questo:

for key,val in d.items():
    print key, 'is the key for ', val
16

Ho un caso d'uso in cui devo ripetere il ditt per ottenere la chiave, coppia di valori, anche l'indice che indica dove sono. Ecco come lo faccio:

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

Notare che le parentesi attorno alla chiave, il valore è importante, senza le parentesi, si ottiene un errore ValueError "valori insufficienti da decomprimere".

12
jdhao

qualunque cosa, oggi, sia python 2.6 e 2.7, sia 3.x, nel mio box funzionano bene con items():

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

Iterare sui dizionari usando i cicli 'for'

d = {'x': 1, 'y': 2, 'z': 3} 
for key in d:
    ...

In che modo Python riconosce che è sufficiente leggere la chiave dal dizionario? La chiave è una parola speciale in Python? O è semplicemente una variabile?

Non sono solo i cicli for. La parola importante qui è "iterating".

Un dizionario è una mappatura delle chiavi ai valori:

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

Ogni volta che lo iteriamo, iteriamo sopra le chiavi. Il nome della variabile key è inteso solo per essere descrittivo - ed è abbastanza adatto allo scopo.

Questo succede in una lista di comprensione:

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

Succede quando passiamo il dizionario per elencare (o qualsiasi altro oggetto del tipo di raccolta):

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

Il modo in cui Python esegue iterazioni è, in un contesto in cui è necessario, chiama il metodo __iter__ dell'oggetto (in questo caso il dizionario) che restituisce un iteratore (in questo caso, un oggetto keyiterator):

>>> d.__iter__()
<dict_keyiterator object at 0x7fb1747bee08>

Non dovremmo usare noi stessi questi metodi speciali, ma usare la rispettiva funzione incorporata per chiamarla, iter:

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

Iterator hanno un metodo __next__ - ma lo chiamiamo con la funzione 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 un iteratore è esaurito, solleva StopIteration. Questo è il modo in cui Python sa di uscire da un ciclo for, o da una list comprehension, da un'espressione di generatore o da qualsiasi altro contesto iterativo. Una volta che un iteratore solleva StopIteration, lo solleverà sempre - se vuoi ripetere l'iterazione, ne hai bisogno di uno nuovo.

>>> list(key_iterator)
[]
>>> new_key_iterator = iter(d)
>>> list(new_key_iterator)
['x', 'y', 'z']

Ritornare a dicts

Abbiamo visto i dettati che iterano in molti contesti. Quello che abbiamo visto è che ogni volta che ripetiamo un ditt, otteniamo le chiavi. Torna all'esempio originale:

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

Se cambiamo il nome della variabile, otteniamo comunque le chiavi. Proviamolo:

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

Se vogliamo iterare sui valori, dobbiamo usare il metodo .values di dicts, o per entrambi insieme, .items:

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

Nell'esempio fornito, sarebbe più efficiente iterare sugli elementi come questo:

for a_key, corresponding_value in d.items():
    print(a_key, corresponding_value)

Ma a fini accademici, l'esempio della domanda va bene.

11
Aaron Hall

Puoi verificare l'implementazione di dicttype di CPython su GitHub. Questa è la firma del metodo che implementa l'iteratore dict:

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

CPython dictobject.c

7
abc

Per iterare sui tasti, è più lento ma meglio usare my_dict.keys(). Se hai provato a fare qualcosa di simile:

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

creerebbe un errore di runtime perché stai cambiando le chiavi mentre il programma è in esecuzione. Se sei assolutamente pronto a ridurre il tempo, usa il modo for key in my_dict, ma sei stato avvisato;).

2

Per key in my_dict è in realtà uguale a per la chiave in my_dict.keys (). Quindi, se vuoi ottenere i valori di dict, puoi provare due metodi.

Uno:

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

Due:

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

Suggerimento di stampa per valori lunghi
Se si hanno stringhe lunghe nei valori, ecco un modo rapido per stamparlo in un formato (più?) Leggibile:
for key, value in my_dictionary.iteritems(): print(key) print("---------") print(value) print("\n")

0
Joseph True