¿Cómo devolver las claves del diccionario como una lista en Python?

784

En Python 2.7 , podría obtener claves de diccionario , valores o elementos como una lista:

>>> newdict = {1:0, 2:0, 3:0}
>>> newdict.keys()
[1, 2, 3]

Ahora, en Python> = 3.3 , obtengo algo como esto:

>>> newdict.keys()
dict_keys([1, 2, 3])

Entonces, tengo que hacer esto para obtener una lista:

newlist = list()
for i in newdict.keys():
    newlist.append(i)

Me pregunto, ¿hay una mejor manera de devolver una lista en Python 3 ?

Dimitris Fasarakis Hilliard
fuente
El tema de seguridad de hilo interesante sobre este tema está aquí: blog.labix.org/2008/06/27/…
Paul
2
Soy nuevo en Python, y para mí parece que esta proliferación de nuevos tipos de datos inútiles es uno de los peores aspectos de Python. ¿De qué sirve este tipo de datos dict_keys? ¿Por qué no una lista?
Phil Goetz

Respuestas:

978

Tratar list(newdict.keys()).

Esto convertirá el dict_keysobjeto en una lista.

Por otro lado, debe preguntarse si importa o no. La forma pitónica de codificar es asumir la escritura de un pato ( si parece un pato y grazna como un pato, es un pato ). El dict_keysobjeto actuará como una lista para la mayoría de los propósitos. Por ejemplo:

for key in newdict.keys():
  print(key)

Obviamente, los operadores de inserción pueden no funcionar, pero eso no tiene mucho sentido para una lista de claves de diccionario de todos modos.

Chris
fuente
49
newdict.keys () no admite indexación
gypaetus
57
list(newdict)También funciona (al menos en Python 3.4). ¿Hay alguna razón para usar el .keys()método?
naught101
46
Nota: en el depurador pdb> list(newdict.keys()) falla porque choca con el comando pdb del mismo nombre. Se usa pdb> !list(newdict.keys())para escapar de los comandos pdb.
Riaz Rizvi
24
@ naught101 Sí, .keys()es mucho más claro sobre lo que sucede.
Felix D.
2
Tenga en cuenta que si usa list (newdict.keys ()), las claves no están en el orden en que las colocó debido al orden de hash.
Nate M
278

Python> = 3.5 alternativa: descomprimir en una lista literal [*newdict]

Se introdujeron nuevas generalizaciones de desempaquetado (PEP 448) con Python 3.5 que le permite ahora hacer fácilmente:

>>> newdict = {1:0, 2:0, 3:0}
>>> [*newdict]
[1, 2, 3]

Desempaquetar *funciona con cualquier objeto que sea iterable y, dado que los diccionarios devuelven sus claves cuando se repiten, puede crear fácilmente una lista usándola dentro de un literal de lista.

Agregar, por .keys()ejemplo, [*newdict.keys()]podría ayudar a que su intento sea un poco más explícito, aunque le costará una búsqueda de funciones e invocación. (que, con toda honestidad, no es algo de lo que realmente deba preocuparse).

La *iterablesintaxis es similar a la de hacer list(iterable)y su comportamiento se documentó inicialmente en la sección Llamadas del manual de referencia de Python. Con PEP 448, la restricción sobre dónde *iterablepodría aparecer se aflojó permitiendo que también se coloque en literales de lista, conjunto y tupla, el manual de referencia en las listas de Expresión también se actualizó para indicar esto.


Aunque es equivalente a list(newdict)la diferencia de que es más rápido (al menos para diccionarios pequeños) porque no se realiza ninguna llamada a la función:

%timeit [*newdict]
1000000 loops, best of 3: 249 ns per loop

%timeit list(newdict)
1000000 loops, best of 3: 508 ns per loop

%timeit [k for k in newdict]
1000000 loops, best of 3: 574 ns per loop

con diccionarios más grandes, la velocidad es prácticamente la misma (la sobrecarga de iterar a través de una gran colección supera el pequeño costo de una llamada a función).


De manera similar, puede crear tuplas y conjuntos de claves de diccionario:

>>> *newdict,
(1, 2, 3)
>>> {*newdict}
{1, 2, 3}

¡cuidado con la coma final en el caso de tupla!

Dimitris Fasarakis Hilliard
fuente
gran explicación, pero por favor, ¿pueden referir cualquier enlace que describa este tipo de sintaxis "* newdict"? Quiero decir cómo y por qué esto devuelve las claves del diccionario solo para su comprensión
Gracias
1
@MYounas Esa sintaxis ha estado disponible durante bastante tiempo, incluso en Python 2. En las llamadas de función puede hacer def foo(*args): print(args)seguido foo(*{1:0, 2:0})con el resultado que (1, 2)se imprime. Este comportamiento se especifica en la sección Llamadas del manual de referencia. Python 3.5 con PEP 448 simplemente aflojó las restricciones sobre dónde pueden aparecer, lo [*{1:0, 2:0}]que permite su uso ahora. De cualquier manera, editaré mi respuesta e incluiré esto.
Dimitris Fasarakis Hilliard
1
*newdict- Esta es definitivamente la respuesta para los golfistas de código; P. Además , lo que, con toda honestidad, no es algo de lo que realmente deba preocuparse , y si lo es, no use python .
Artemis todavía no confía en SE
46

list(newdict)funciona en Python 2 y Python 3, proporcionando una lista simple de las claves en newdict. keys()no es necesario (:

Seb
fuente
26

Un poco fuera de lugar en la definición de "escritura de pato": dict.keys()devuelve un objeto iterable, no un objeto tipo lista. Funcionará en cualquier lugar que funcione un iterable, no en cualquier lugar donde funcione una lista. una lista también es iterable, pero un iterable NO es una lista (o secuencia ...)

En casos de uso reales, lo más común con las claves en un dict es iterar a través de ellas, por lo que tiene sentido. Y si los necesita como una lista, puede llamar list().

De manera muy similar zip(), en la gran mayoría de los casos, se repite, ¿por qué crear una lista completamente nueva de tuplas solo para iterar y luego tirarla de nuevo?

Esto es parte de una gran tendencia en Python para usar más iteradores (y generadores), en lugar de copias de listas por todo el lugar.

dict.keys() Sin embargo, debería funcionar con las comprensiones: compruebe cuidadosamente los errores tipográficos o algo así ... funciona bien para mí:

>>> d = dict(zip(['Sounder V Depth, F', 'Vessel Latitude, Degrees-Minutes'], [None, None]))
>>> [key.split(", ") for key in d.keys()]
[['Sounder V Depth', 'F'], ['Vessel Latitude', 'Degrees-Minutes']]
Chris Barker
fuente
2
Ni siquiera necesitas usar .keys(); el objeto de diccionario es en sí iterable y produce teclas cuando se repiten a lo largo: [key.split(", ") for key in d].
Martijn Pieters
25

También puede usar una lista de comprensión :

>>> newdict = {1:0, 2:0, 3:0}
>>> [k  for  k in  newdict.keys()]
[1, 2, 3]

O, más corto,

>>> [k  for  k in  newdict]
[1, 2, 3]

Nota: El pedido no está garantizado en versiones anteriores a 3.7 (el pedido sigue siendo solo un detalle de implementación con CPython 3.6).

未来 陆家嘴 顶尖 的 投资 人
fuente
66
Solo úsalo list(newdict). No hay necesidad de una lista de comprensión aquí.
Martijn Pieters
8

La conversión a una lista sin usar el keysmétodo lo hace más legible:

list(newdict)

y, al recorrer los diccionarios, no hay necesidad de keys():

for key in newdict:
    print key

a menos que lo esté modificando dentro del ciclo que requeriría una lista de claves creadas de antemano:

for key in list(newdict):
    del newdict[key]

En Python 2 hay un aumento marginal de rendimiento conkeys() .

Cas
fuente
8

Si necesita almacenar las claves por separado, aquí hay una solución que requiere menos tipeo que cualquier otra solución presentada hasta ahora, utilizando el Desembalaje Iterable Extendido (python3.x +).

newdict = {1: 0, 2: 0, 3: 0}
*k, = newdict

k
# [1, 2, 3]

            ╒═══════════════╤═════════════════════════════════════════╕
             k = list(d)      9 characters (excluding whitespace)   
            ├───────────────┼─────────────────────────────────────────┤
             k = [*d]         6 characters                          
            ├───────────────┼─────────────────────────────────────────┤
             *k, = d          5 characters                          
            ╘═══════════════╧═════════════════════════════════════════╛
cs95
fuente
1
La única advertencia menor que señalaría es que ksiempre hay una lista aquí. Si un usuario quiere una tupla o un conjunto de teclas, deberá recurrir a las otras opciones.
Dimitris Fasarakis Hilliard
1
Una nota más notable es el hecho de que, como una declaración, *k, = dtiene limitaciones sobre dónde puede aparecer (pero vea, y quizás actualice esta respuesta para, PEP 572 : el desempaquetado extendido no es compatible con las expresiones de asignación atm, ¡ pero podría ser algún día! )
Dimitris Fasarakis Hilliard
¿Qué sucede si desea que tanto las claves como los valores estén en listas?
endolito el
1
@endolith quizás keys, vals = zip(*d.items())(aunque eso da dos tuplas, lo suficientemente cerca). No sé de una expresión más corta que esta.
cs95
1

Puedo pensar en 2 formas en que podemos extraer las claves del diccionario.

Método 1: - Para obtener las claves utilizando el método .keys () y luego convertirlo a la lista.

some_dict = {1: 'one', 2: 'two', 3: 'three'}
list_of_keys = list(some_dict.keys())
print(list_of_keys)
-->[1,2,3]

Método 2: - Para crear una lista vacía y luego agregar claves a la lista a través de un bucle. También puede obtener los valores con este bucle (use .keys () solo para claves y .items () para extracción de claves y valores)

list_of_keys = []
list_of_values = []
for key,val in some_dict.items():
    list_of_keys.append(key)
    list_of_values.append(val)

print(list_of_keys)
-->[1,2,3]

print(list_of_values)
-->['one','two','three']
Rahul
fuente