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

7 minutos de lectura

Con Python 2.7, puedo obtener un diccionario llaves, valoreso elementos como un list:

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

Con Python >= 3.3, obtengo:

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

como consigo un llano list de claves con Python 3?

  • Soy nuevo en Python, y me 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

    9 de abril de 2020 a las 20:22

  • @PhilGoetz ahorra memoria al crear un vista en el diccionario que puede usar todos los datos del diccionario, en lugar de tener que almacenar una lista de muchos elementos. También proporciona algunas operaciones de conjuntos (es decir, puede aprovechar el hecho de que “sabe” que no contiene duplicados), que son más eficientes que verificar, por ejemplo, la intersección de dos listas.

    – Karl Knechtel

    29 de agosto de 2022 a las 13:08


Avatar de usuario de Chris
cris

Esto convertirá el dict_keys objetar a un list:

list(newdict.keys())

Por otro lado, debes preguntarte si importa o no. Es pitónico suponer pato escribiendosi parece un pato y grazna como un pato, es un pato. El dict_keys El objeto se puede iterar como un list. Por ejemplo:

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

Tenga en cuenta que dict_keys no admite la inserción newdict[k] = vaunque es posible que no lo necesite.

  • newdict.keys() no admite la indexación

    – gipaetus

    10/09/2014 a las 17:54

  • list(newdict) también funciona (al menos en python 3.4). ¿Hay alguna razón para usar el .keys() ¿método?

    – nada101

    31 de marzo de 2015 a las 11:58


  • Nota: en el depurador pdb> list(newdict.keys()) falla porque choca con el comando de pdb del mismo nombre. Usar pdb> !list(newdict.keys()) para escapar de los comandos pdb.

    – Riaz Rizvi

    24 dic 2016 a las 20:37

  • @naught101 Sí, .keys() es mucho más claro sobre lo que sucede.

    – Félix D.

    27 mayo 2018 a las 21:43

  • ¡Tenga en cuenta que si usa list(newdict.keys()) las claves no están en el orden en que las colocó debido al orden hash!

    – Nate M.

    30 de enero de 2019 a las 3:28

Avatar de usuario de Dimitris Fasarakis Hilliard
Dimitris Fasarakis Hilliard

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

Nuevo desempacando generalizaciones (PEP 448) se introdujeron con Python 3.5, lo que le permite ahora hacer fácilmente:

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

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

agregando .keys() es decir [*newdict.keys()] podría ayudar a que su intención sea un poco más explícita, aunque le costará una función de búsqueda e invocación. (que, con toda honestidad, no es algo que debas en realidad preocuparse de).

El *iterable la sintaxis es similar a hacer list(iterable) y su comportamiento fue inicialmente documentado en el Sección de llamadas del manual de referencia de Python. Con PEP 448 la restricción de dónde *iterable podría aparecer se aflojó permitiendo que también se coloque en literales de lista, conjunto y tupla, el manual de referencia en Listas de expresiones también se actualizó para indicar esto.


Aunque equivalente a list(newdict) con la diferencia de que es más rápido (al menos para diccionarios pequeños) porque en realidad no se realiza ninguna llamada de 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 más o menos la misma (la sobrecarga de iterar a través de una gran colección supera el pequeño costo de una llamada de 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 la tupla!

  • excelente explicación, pero puede consultar cualquier enlace que describa este tipo de sintaxis “* newdict”, me refiero a cómo y por qué esto devuelve las claves del diccionario solo para comprenderlo. Gracias

    – Muhammad Yunus

    7 de abril de 2018 a las 2:56


  • @MYonas Esa sintaxis ha estado disponible durante bastante tiempo, incluso en Python 2. En las llamadas a funciones que puede hacer def foo(*args): print(args) seguido por foo(*{1:0, 2:0}) con el resultado (1, 2) siendo impreso. Este comportamiento se especifica en el Llamadas sección del manual de referencia. Python 3.5 con PEP 448 acaba de aflojar las restricciones sobre dónde pueden aparecer, lo que permite [*{1:0, 2:0}] para ser usado ahora. De cualquier manera, editaré mi respuesta e incluiré estos.

    – Dimitris Fasarakis Hilliard

    7 abr 2018 a las 10:56


  • *newdict – esta es definitivamente la respuesta para los golfistas de código; P. También: lo cual, con toda honestidad, no es algo que realmente deba preocuparte – y si lo eres, no uses python.

    – Artemisa

    5 de abril de 2019 a las 14:26


  • Aprendí dos cosas hoy: 1. Puedo acortar list(some_dict.keys()) a [*some_dict]2. la expresión ‘código golfista’ (y 2a. el significado de ‘código golfista’ – después de buscarlo en Google)

    – kasimir

    8 de julio de 2020 a las 12:16

Avatar de usuario de Seb
Seb

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

Avatar de usuario de 未来陆家嘴顶尖的投资人
未来陆家嘴顶尖的投资人

También puedes usar un 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 las versiones anteriores a la 3.7 (el pedido sigue siendo solo un detalle de implementación con CPython 3.6).

Un poco fuera de lugar en la definición de “escribir pato” — dict.keys() devuelve un objeto iterable, no un objeto similar a una lista. Funcionará en cualquier lugar donde funcione un iterable, no en cualquier lugar donde lo haga 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 que se puede hacer 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 para 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 de usar más iteradores (y generadores), en lugar de copias de listas por todas partes.

dict.keys() Sin embargo, debería funcionar con comprensiones: verifique 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']]

  • Ni siquiera necesitas usar .keys(); el objeto del diccionario es sí mismo iterable y produce claves cuando se itera sobre: [key.split(", ") for key in d].

    – Martijn Pieters

    27 de septiembre de 2019 a las 12:16


Avatar de usuario de Tomerikoo
Tomerikoo

Si necesita almacenar las claves por separado, aquí hay una solución que requiere escribir menos que cualquier otra solución presentada hasta ahora, usando Desempaquetado Iterable Extendido (Python3.x+):

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

k
# [1, 2, 3]

Operación No. de personajes
k = list(d) 9 caracteres (excluyendo espacios en blanco)
k = [*d] 6 caracteres
*k, = d 5 caracteres

  • Ni siquiera necesitas usar .keys(); el objeto del diccionario es sí mismo iterable y produce claves cuando se itera sobre: [key.split(", ") for key in d].

    – Martijn Pieters

    27 de septiembre de 2019 a las 12:16


Avatar de usuario de Dimitris Fasarakis Hilliard
Dimitris Fasarakis Hilliard

Convertir a una lista sin usar el keys El mé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, lo que requeriría una lista de claves creada de antemano:

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

En Python 2 hay una ganancia de rendimiento marginal usando keys().

¿Ha sido útil esta solución?