Crea un diccionario con comprensión de listas

1420

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

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

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

Utilice una comprensión de dictado :

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

Nota: esto es para Python 3.x (y 2.7 en adelante). Anteriormente en Python 2.6 y versiones anteriores, el dictintegrado podía recibir un iterable de pares clave / valor, por lo que puede pasarle una comprensión de lista o una expresión generadora. Por ejemplo:

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

En casos simples, no necesitas comprensión en absoluto ...

Pero si ya tiene iterables de claves y / o valores, simplemente llame al dictintegrado directamente:

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

2) "zip'ped" from two separate iterables of keys/vals
dict(zip(list_of_keys, list_of_values))
2
  • 1
    ¿Qué pasa si tengo un caso de lista de palabras ['gato', 'perro', 'gato'] y quiero hacer un dict con la clave como palabra y el valor como recuento? ¿Existe una sintaxis breve y eficiente para eso? 14/07/19 a las 2:30
  • @cryanbhu si lo que quiere decir es contar las repeticiones de un elemento dado en la lista, hay una clase Counter en el paquete de colecciones: docs.python.org/2/library/collections.html#collections.Counter
    fortran
    19/07/19 a las 5:52
256

En Python 3 y Python 2.7+, las comprensiones del diccionario tienen el siguiente aspecto:

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

Para Python 2.6 o anterior, consulte la respuesta de fortran .

0
66

De hecho, ni siquiera necesita iterar sobre el iterable si ya comprende algún tipo de mapeo, el constructor dict lo hace amablemente 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}
0
44

En Python 2.7, dice lo siguiente:

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

¡Ciérralos !

1
41

Create a dictionary with list comprehension in Python

I like the Python list comprehension syntax.

Can it be used to create dictionaries too? For example, by iterating over pairs of keys and values:

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

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

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

Suponiendo que blah blah blahes un iterable de dos tuplas, estás tan cerca. Creemos algunos "blahs" como ese:

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

Sintaxis de Dict Comprension:

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 a su pseudocódigo) son los dos puntos, :como se muestra a continuación:

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

Y vemos que funcionó y debería conservar 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.

Entonces puede 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 mapear las claves y los valores.

28

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

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

Python versión <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])
23

Para agregar a la respuesta de @ fortran, si desea iterar sobre una lista de claves key_list, así como 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 de dict:

Lo que intento 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 aquí 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 le dé una buena idea de la composición del diccionario y lo anime a usarlo con más frecuencia para hacer que su código sea compacto

1
  • 1
    Buena respuesta, simplificada: d = {k: v+1 for v, k in enumerate(string.ascii_lowercase)} 6 feb 2018 a las 20:17
5

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 de países y capitales.

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

Luego crea 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'}
1
  • 9
    podrías haber usado zip 16/10/2016 a las 15:24
4

Este código creará un diccionario usando la comprensión de listas para múltiples listas con diferentes valores que se pueden usar 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)}

#Convert dict to dataframe
df=pd.DataFrame(data)
display(df)

enumeratepasará na valspara hacer coincidir cada uno keycon su lista

0
3

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 de la lista. Puede hacerlo con la siguiente línea de código:

{index:nums[index] for index in range(0,len(nums))}
2
>>> {k: v**3 for (k, v) in zip(string.ascii_lowercase, range(26))}

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

Una comprensión de diccionario toma la forma {clave: valor para (clave, valor) en iterable}. Esta sintaxis se introdujo en Python 3 y se actualizó 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.

Producción:

{'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}
0

Si es posible. En Python, Comprehension se puede usar en List, Set, Dictionary, etc. Puede escribirlo de esta manera

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

Otro ejemplo detallado de Comprensión de diccionario con declaración condicional y bucle:

parents = [father, mother]
            
parents = {parent:1 - P["mutation"] if parent in two_genes else 0.5 if parent in one_gene else P["mutation"] for parent in parents}
-1

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

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

Obviamente, este enfoque requiere reducede functools.

1
  • misma idea: reducir (lambda p, q: {** p, ** dict ([q])}, bla bla bla, {}) 1 dic 2019 a las 17:05