2012-01-21 9 views
39

Estoy tratando de usar el .keys() y en lugar de obtener una lista de las claves como siempre tengo en el pasado. Sin embargo, entiendo esto.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']) 

que sólo debe imprimir [ 'música', 'video'] a no ser que me estoy volviendo loco.

¿Qué está pasando?

+3

Ya que nadie vinculado la documentación oficial, lo haré: [** Diccionario Vista del objeto **] (http: //docs.python. org/py3k/library/stdtypes.html # dictionary-view-objects). –

+0

Tenga en cuenta que los diccionarios no están ordenados, de modo que b.keys() [0] generalmente no es una tarea muy útil. –

Respuesta

85

Python 3 cambió el comportamiento de dict.keys de tal manera que ahora devuelve un objeto dict_keys, que es iterable pero no indexable (que es como el viejo dict.iterkeys, que se ha ido ahora). Usted puede obtener el resultado Python 2 de vuelta con una llamada explícita a list:

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

o simplemente

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

simplemente 'list (b)' hace lo mismo –

+2

@JochenRitzel: ¡buen punto, lo agregó! –

+0

Veo gracias. Entonces, ¿cómo harías para iterar a través de dict_keys? – tokageKitayama

8

Si ha asignado k así:

k = list(b.keys()) 

su código funcionará.

Como dice el error, el tipo dict_keys no admite la indexación.

2

Este es uno de los cambios de ruptura entre Python 2 y 3.

en Python 2:

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

En Python 3:

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

Este cambio de comportamiento tiene mucho de sentido, ya que un dict está semánticamente desordenado y sus claves son únicas, como un conjunto.

Este cambio significa que no tiene que crear una nueva lista de claves cada vez que desee hacer algún tipo de comparación de conjuntos con las teclas de un dict.

Conseguir el mismo comportamiento en 2 y 3

Para ayudar a la transición a Python 3, Python 2.7 tiene otro método dict, viewkeys.El método viewkeys es más similar a dict.keys método de 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']) 

En Python 3, el análogo más cercano al comportamiento anterior es pasar dict.keys() a list:

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

O simplemente pasar el dict a list, ya que un diccionario será iterar sobre sus claves de todos modos:

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

Usted podría cr eate unas funciones de utilidad para abstraer el comportamiento a lo largo 2 y 3:

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

y pasar un diccionario de list para obtener el formulario de lista, y en ambos 2 y 3, que obtendrá el mismo resultado:

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

Si simplemente desea una lista de claves de un diccionario que puede hacer directamente como esto:

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

KEY_LIST contendrá todos los nombres de las teclas en forma de lista, sin embargo, esto no se repite una tecla, si fou y más de una vez Las claves duplicadas se contarán como una sola.

-1

problema se resuelve: Primero: la importación al azar

>>> 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

Debería escribir más detalles con respecto a la respuesta (ingresar la respuesta de texto y la explicación, ¿por qué algo funciona de esa manera)? + Usar mejor formateo para el código directamente (para mantener los estándares para el SO). – Tatranskymedved