Crea un diccionario con comprensión de listas


1280

Me gusta la sintaxis de comprensión de la lista de Python.

¿Se puede usar para crear diccionarios también? Por ejemplo, iterando sobre pares de claves y valores:

mydict = {(k,v) for (k,v) in blah blah blah}  # doesn't work

Relacionado: collections.Counteres un tipo especializado de dict para contar cosas: Usar un diccionario para contar los elementos de una lista
smci

Respuestas:


1898

Desde Python 2.7 y 3 en adelante, solo debe usar la sintaxis de comprensión dict :

{key: value for (key, value) in iterable}

En Python 2.6 y versiones anteriores, el dictincorporado puede recibir un iterable de pares clave / valor, por lo que puede pasarle una comprensión de lista o una expresión de generador. Por ejemplo:

dict((key, func(key)) for key in keys)

Sin embargo, si ya tiene iterable (s) de claves y / o valores, no necesita usar una comprensión en absoluto; es más simple, simplemente llame dictdirectamente al incorporado:

# consumed from any iterable yielding pairs of keys/vals
dict(pairs)

# "zipped" from two separate iterables of keys/vals
dict(zip(list_of_keys, list_of_values))

1
¿Qué sucede si tengo un caso de lista de palabras ['gato', 'perro', 'gato'] y quiero hacer un dict con clave como palabra y valor como recuento? ¿Existe una sintaxis eficiente corta para eso?
cryanbhu

@cryanbhu si lo que quiere decir es contar las repeticiones de un elemento dado en la lista, hay una clase de contador en el paquete colecciones: docs.python.org/2/library/collections.html#collections.Counter
FORTRAN


57

De hecho, ni siquiera necesita iterar sobre el iterable si ya comprende algún tipo de mapeo, el constructor dict lo hace gentilmente por usted:

>>> ts = [(1, 2), (3, 4), (5, 6)]
>>> dict(ts)
{1: 2, 3: 4, 5: 6}
>>> gen = ((i, i+1) for i in range(1, 6, 2))
>>> gen
<generator object <genexpr> at 0xb7201c5c>
>>> dict(gen)
{1: 2, 3: 4, 5: 6}

40

En Python 2.7, dice así:

>>> list1, list2 = ['a', 'b', 'c'], [1,2,3]
>>> dict( zip( list1, list2))
{'a': 1, 'c': 3, 'b': 2}

¡Ciérrelos !


11
Esto no aborda la pregunta en absoluto.
Jean-François Corbett

32

Crear un diccionario con comprensión de listas en Python

Me gusta la sintaxis de comprensión de la lista de Python.

¿Se puede usar para crear diccionarios también? Por ejemplo, iterando sobre pares de claves y valores:

mydict = {(k,v) for (k,v) in blah blah blah}

Estás buscando la frase "comprensión dict", en realidad es:

mydict = {k: v for k, v in iterable}

Suponiendo que blah blah blahes un iterable de dos tuplas, estás muy cerca. Creemos algunos "blahs" así:

blahs = [('blah0', 'blah'), ('blah1', 'blah'), ('blah2', 'blah'), ('blah3', 'blah')]

Dict sintaxis de comprensión:

Ahora la sintaxis aquí es la parte de mapeo. Lo que hace que esto sea una dictcomprensión en lugar de una setcomprensión (que es lo que se aproxima su pseudocódigo) es el colon, :como a continuación:

mydict = {k: v for k, v in blahs}

Y vemos que funcionó, y debería retener el orden de inserción a partir de Python 3.7:

>>> mydict
{'blah0': 'blah', 'blah1': 'blah', 'blah2': 'blah', 'blah3': 'blah'}

En Python 2 y hasta 3.6, el orden no estaba garantizado:

>>> mydict
{'blah0': 'blah', 'blah1': 'blah', 'blah3': 'blah', 'blah2': 'blah'}

Agregar un filtro:

Todas las comprensiones cuentan con un componente de mapeo y un componente de filtrado que puede proporcionar con expresiones arbitrarias.

Para que pueda agregar una parte de filtro al final:

>>> mydict = {k: v for k, v in blahs if not int(k[-1]) % 2}
>>> mydict
{'blah0': 'blah', 'blah2': 'blah'}

Aquí solo estamos probando si el último carácter es divisible por 2 para filtrar los datos antes de asignar las claves y los valores.


23

Versión de Python <2.7 (RIP, 3 de julio de 2010 - 31 de diciembre de 2019) , haga lo siguiente:

d = dict((i,True) for i in [1,2,3])

Versión de Python> = 2.7, haga lo siguiente:

d = {i: True for i in [1,2,3]}

22

Para agregar a la respuesta de @ fortran, si desea iterar sobre una lista de claves key_listy una lista de valores value_list:

d = dict((key, value) for (key, value) in zip(key_list, value_list))

o

d = {(key, value) for (key, value) in zip(key_list, value_list)}

6

Aquí hay otro ejemplo de creación de diccionario usando la comprensión dict:

Lo que estoy tratando de hacer aquí es crear un diccionario alfabético donde cada par; es la letra inglesa y su posición correspondiente en el alfabeto inglés

>>> import string
>>> dict1 = {value: (int(key) + 1) for key, value in 
enumerate(list(string.ascii_lowercase))}
>>> dict1
{'a': 1, 'c': 3, 'b': 2, 'e': 5, 'd': 4, 'g': 7, 'f': 6, 'i': 9, 'h': 8, 
'k': 11, 'j': 10, 'm': 13, 'l': 12, 'o': 15, 'n': 14, 'q': 17, 'p': 16, 's': 
19, 'r': 18, 'u': 21, 't': 20, 'w': 23, 'v': 22, 'y': 25, 'x': 24, 'z': 26}
>>> 

Observe el uso de enumerate here para obtener una lista de alfabetos y sus índices en la lista y el intercambio de alfabetos e índices para generar el par de valores clave para el diccionario

Espero que te dé una buena idea de compilación de diccionario y te aliente a usarlo más a menudo para hacer que tu código sea compacto


1
Buena respuesta - simplificado:d = {k: v+1 for v, k in enumerate(string.ascii_lowercase)}
johnnydrama

4

Prueba esto,

def get_dic_from_two_lists(keys, values):
    return { keys[i] : values[i] for i in range(len(keys)) }

Supongamos que tenemos dos listas país y capital

country = ['India', 'Pakistan', 'China']
capital = ['New Delhi', 'Islamabad', 'Beijing']

Luego cree un diccionario a partir de las dos listas:

print get_dic_from_two_lists(country, capital)

La salida es así,

{'Pakistan': 'Islamabad', 'China': 'Beijing', 'India': 'New Delhi'}

99
podrías haber usado zip
Andre Simon

2
>>> {k: v**3 for (k, v) in zip(string.ascii_lowercase, range(26))}

Python admite comprensiones dict, que le permiten expresar la creación de diccionarios en tiempo de ejecución utilizando una sintaxis concisa similar.

Una comprensión del diccionario toma la forma {clave: valor para (clave, valor) en iterable}. Esta sintaxis se introdujo en Python 3 y se retrocedió hasta Python 2.7, por lo que debería poder usarla independientemente de la versión de Python que haya instalado.

Un ejemplo canónico es tomar dos listas y crear un diccionario donde el elemento en cada posición en la primera lista se convierte en una clave y el elemento en la posición correspondiente en la segunda lista se convierte en el valor.

La función zip utilizada dentro de esta comprensión devuelve un iterador de tuplas, donde cada elemento de la tupla se toma de la misma posición en cada uno de los iterables de entrada. En el ejemplo anterior, el iterador devuelto contiene las tuplas ("a", 1), ("b", 2), etc.

Salida:

{'i': 512, 'e': 64, 'o': 2744, 'h': 343, 'l': 1331, 's': 5832, 'b': 1, 'w': 10648, ' c ': 8,' x ': 12167,' y ': 13824,' t ': 6859,' p ': 3375,' d ': 27,' j ': 729,' a ': 0,' z ' : 15625, 'f': 125, 'q': 4096, 'u': 8000, 'n': 2197, 'm': 1728, 'r': 4913, 'k': 1000, 'g': 216 , 'v': 9261}


2

Este código creará un diccionario usando la comprensión de listas para múltiples listas con diferentes valores que pueden usarse para pd.DataFrame()

#Multiple lists 
model=['A', 'B', 'C', 'D']
launched=[1983,1984,1984,1984]
discontinued=[1986, 1985, 1984, 1986]

#Dictionary with list comprehension
keys=['model','launched','discontinued']
vals=[model, launched,discontinued]
data = {key:vals[n] for n, key in enumerate(keys)}

enumeratepasará na valscoincidir cada uno keycon su lista


1

Solo para poner otro ejemplo. Imagina que tienes la siguiente lista:

nums = [4,2,2,1,3]

y desea convertirlo en un dict donde la clave es el índice y el valor es el elemento en la lista. Puede hacerlo con la siguiente línea de código:

{index:nums[index] for index in range(0,len(nums))}

0

Puede crear un nuevo dict para cada par y combinarlo con el dict anterior:

reduce(lambda p, q: {**p, **{q[0]: q[1]}}, bla bla bla, {})

Obviamente este enfoque requiere reducede functools.


misma idea: reducir (lambda p, q: {** p, ** dict ([q])}, bla bla bla, {})
Mahmoud Khaled
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.