2012-01-21 5 views
39

Sto cercando di utilizzare lo .keys() e invece di ottenere un elenco di chiavi come sempre in passato. Comunque ho capito.Python dictionary.keys() error

b = { 'video':0, 'music':23 } 
k = b.keys() 
print(k[0]) 

>>>TypeError: 'dict_keys' object does not support indexing 

print(k) 
dict_keys(['music', 'video']) 

dovrebbe solo stampare ['musica', 'video'] a meno che non stia impazzendo.

Cosa sta succedendo?

+3

Dal momento che nessuno ha collegato la documentazione ufficiale ancora, lo farò: [** vista Dizionario oggetto **] (http: //docs.python. org/py3k/library/stdtypes.html # dizionario-view-oggetti). –

+0

Si noti che i dizionari non sono ordinati, quindi b.keys() [0] non è generalmente una cosa molto utile da fare. –

risposta

85

Python 3 ha cambiato il comportamento di dict.keys tale che ora restituisce un oggetto dict_keys, che è iterabile ma non indicizzabili (è come il vecchio dict.iterkeys, che è andato ora). È possibile ottenere il risultato Python 2 indietro con una chiamata esplicita a list:

>>> b = { 'video':0, 'music':23 } 
>>> k = list(b.keys()) 
>>> k 
['music', 'video'] 

o semplicemente

>>> list(b) 
['music', 'video'] 
+14

just 'list (b)' fa lo stesso –

+2

@JochenRitzel: buon punto, lo ha aggiunto! –

+0

Io vedo grazie. Quindi, come andresti a ripetere attraverso i dict_keys? – tokageKitayama

8

Se hai assegnato k in questo modo:

k = list(b.keys()) 

il codice funzionerà.

Come dice l'errore, il tipo dict_keys non supporta l'indicizzazione.

2

Questo è uno dei rottura modifiche tra Python 2 e 3.

In Python 2:

>>> help(dict.keys) 
keys(...) 
    D.keys() -> list of D's keys 

In Python 3:

>>> help(dict.keys) 
keys(...) 
    D.keys() -> a set-like object providing a view on D's keys 

Questa modifica del comportamento rende molto di senso dato che un dict è semanticamente non ordinato e le sue chiavi sono uniche - proprio come un set.

Questo cambiamento significa che non è necessario creare un nuovo elenco di chiavi ogni volta che si desidera eseguire una sorta di confronto di set con i tasti di un dict.

ottenere lo stesso comportamento in 2 e 3

Per aiutare la transizione a Python 3, Python 2.7 ha un altro metodo dict, viewkeys.Il metodo viewkeys è più simile a dict.keys il metodo di Python 3:

>>> d 
{'a': None, 'c': None, 'b': None, 'd': None} 
>>> for k in d.viewkeys(): print k 
... 
a 
c 
b 
d 
>>> d.viewkeys() & set('abc') 
set(['a', 'c', 'b']) 

In Python 3, l'analogo più vicino al vecchio comportamento è quello di passare dict.keys() a list:

>>> d 
{'d': None, 'a': None, 'c': None, 'b': None} 
>>> list(d.keys()) 
['d', 'a', 'c', 'b'] 

O semplicemente passare il dict a list, dal momento che un dict sarà iterare su suoi tasti in ogni modo:

>>> list(d) 
['d', 'a', 'c', 'b'] 

si poteva cr EATE a funzioni di utilità di astrarre il comportamento nel 2 e 3:

if hasattr(dict, 'viewkeys'): # Python 2.7 
    def keys(d): 
     return d.viewkeys() 
else: # Python 3 
    def keys(d): 
     return d.keys() 

e passare un dict per list per ottenere la forma di lista, e in entrambi i 2 e 3, si otterrà lo stesso risultato:

>>> d 
{'b': None, 'a': None, 'c': None, 'd': None} 
>>> keys(d) 
dict_keys(['b', 'a', 'c', 'd']) 
>>> list(d) 
['b', 'a', 'c', 'd'] 
0

Se si desidera semplicemente un elenco di chiavi da un dizionario si può direttamente fare come questo:

b = {"name": "xyz", "class":"abc", "college": "qwert"} 
key_list = list(b) 

KEY_LIST conterrà tutti i nomi dei tasti come una lista, però, questo non ripete un tasto, se fou e più di una volta. Le chiavi duplicate verranno conteggiate come una sola.

-1

problema è risolto: Primo: import casuale

>>> b = { 'video':0, 'music':23,"picture":12 } 
>>> random.choice(tuple(b.items())) 
('music', 23) 
>>> random.choice(tuple(b.items())) 
('music', 23) 
>>> random.choice(tuple(b.items())) 
('picture', 12) 
>>> random.choice(tuple(b.items())) 
('video', 0) 
>>> 
+0

Dovresti scrivere più dettagli riguardanti la risposta (inserendo testo risposta e spiegazione, perché qualcosa funziona in questo modo) + usa meglio la formulazione per il codice direttamente (per mantenere gli standard per la SO). – Tatranskymedved