2013-08-31 13 views
50

Sto cercando di accedere elemento di un dict_key dal suo indice:Accesso elemento dict_keys dall'indice in python3

test = {'foo': 'bar', 'hello': 'world'} 
keys = test.keys() # dict_keys object 

keys.index(0) 
AttributeError: 'dict_keys' object has no attribute 'index' 

voglio arrivare foo.

stesso con:

keys[0] 
TypeError: 'dict_keys' object does not support indexing 

Come posso fare questo?

+6

In py3.x 'dict.keys()' restituisce un set come oggetto vista, non lista (quindi, l'indicizzazione non è possibile). Utilizzare 'keys = list (test)' –

+0

quando faccio una lista (something_dict), l'ordine della tupla è casuale: esempio: list ({'foo': 'bar', 'hello': 'world'}) può restituire : lista (foo, ciao) o lista (ciao, foo), perché è casuale? – fj123x

+1

[I dizionari non hanno alcun ordine] (http://stackoverflow.com/questions/526125/why-is-python-ordering-my-dictionary-like-so). (Usa 'collections.OrderedDict' se vuoi chiavi ordinate) –

risposta

64

chiamata list() sul dizionario, invece:

keys = list(test) 

In Python 3, il metodo restituisce un dict.keys()dictionary view object, che agisce come un insieme. Scorrere il dizionario direttamente produce anche chiavi, in modo da trasformare un dizionario in un elenco di risultati in un elenco di tutte le chiavi:

>>> test = {'foo': 'bar', 'hello': 'world'} 
>>> list(test) 
['foo', 'hello'] 
>>> list(test)[0] 
'foo' 
+2

[ Fai attenzione alla lista (dict.keys()) in Python 3 - Labix Blog] (http://blog.labix.org/2008/06/27/watch-out-for-listdictkeys-in-python-3) chiaramente spiega qual è il problema senza fornire una soluzione. Questo è eccellente! –

+0

@BrandonBradley: in generale: affidarsi ad alcune azioni atomiche è comunque una cattiva idea, dato che Python è così altamente dinamico. Il tuo codice può essere facilmente passato ad una sottoclasse 'dict', per esempio, dove' .keys() 'viene gestito in codice Python (ad esempio può avvenire un cambio di thread). –

25
Non

una risposta completa, ma forse un suggerimento utile. Se è davvero il primo elemento che si desidera *, quindi

next(iter(q)) 

è molto più veloce di

list(q)[0] 

per grandi dicts, dal momento che il tutto non deve essere memorizzato.

Per 10.000.000 articoli l'ho trovato quasi 40.000 volte più veloce.

* Il primo elemento nel caso in cui un dict sia solo un elemento pseudo-casuale prima di Python 3.6 (dopo che è stato ordinato nell'implementazione standard, anche se non è consigliabile fare affidamento su di esso).

+0

Questo è sempre stato uno dei miei maggiori problemi con tutto ciò che è diventato iteratore in Py3. È sicuramente più efficiente, ma tanti casi d'uso diventano "sporchi" e complicati senza motivo. Ad esempio, perché non possono semplicemente supportare l'indicizzazione sull'iteratore, senza necessariamente avere una perdita di prestazioni? –