python list dictionary

python - Cómo fusionar dos listas en el diccionario sin usar el bucle anidado para



dictionary (7)

Tengo dos listas:

a = [0, 0, 0, 1, 1, 1, 1, 1, .... 99999] b = [24, 53, 88, 32, 45, 24, 88, 53, ...... 1]

Quiero unir esas dos listas en un diccionario como:

{ 0: [24, 53, 88], 1: [32, 45, 24, 88, 53], ...... 99999: [1] }

Una solución podría estar utilizando for bucle, que no se ve bien y elegante, como:

d = {} unique_a = list(set(list_a)) for i in range(len(list_a)): if list_a[i] in d.keys: d[list_a[i]].append(list_b[i]) else: d[list_a] = [list_b[i]]

Aunque esto funciona, es ineficiente y tomaría mucho tiempo cuando la lista es extremadamente grande. ¿Quiero conocer formas más elegantes de construir un diccionario así?

¡Gracias por adelantado!


No hay estructuras extravagantes, solo un simple diccionario.

d = {} for x, y in zip(a, b): d.setdefault(x, []).append(y)


O haga una comprensión del diccionario de antemano, ya que todas las claves están allí con valores de listas vacías, iterar a través del zip de las dos listas, luego agregar el valor de la segunda lista a la clave del diccionario nombrando el valor de la primera lista, sin necesidad de una cláusula de prueba (excepto) o si es una declaración), para ver si la clave existe o no, debido a la comprensión previa del diccionario:

d={k:[] for k in l} for x,y in zip(l,l2): d[x].append(y)

Ahora:

print(d)

Es:

{0: [24, 53, 88], 1: [32, 45, 24, 88, 53], 9999: [1]}


Puedes hacer esto con una comprensión de dictado:

list_a = [0, 0, 0, 1, 1, 1, 1, 1] list_b = [24, 53, 88, 32, 45, 24, 88, 53] my_dict = {key: [] for key in set(a)} # my_dict = {0: [], 1: []} for a, b in zip(list_a, list_b): my_dict[a].append(b) # {0: [24, 53, 88], 1: [32, 45, 24, 88, 53]}

Por extraño que parezca, parece que no puede hacer que esto funcione utilizando dict.fromkeys(set(list_a), []) ya que esto establecerá el valor de todas las claves igual a la misma matriz vacía:

my_dict = dict.fromkeys(set(list_a), []) # my_dict = {0: [], 1: []} my_dict[0].append(1) # my_dict = {0: [1], 1: [1]}


Puedes usar un defaultdict :

from collections import defaultdict d = defaultdict(list) list_a = [0, 0, 0, 1, 1, 1, 1, 1, 9999] list_b = [24, 53, 88, 32, 45, 24, 88, 53, 1] for a, b in zip(list_a, list_b): d[a].append(b) print(dict(d))

Salida:

{0: [24, 53, 88], 1: [32, 45, 24, 88, 53], 9999: [1]}


Quizás pierda el punto, pero al menos intentaré ayudar. Si tiene que listas y quiere ponerlas en el dict, haga lo siguiente

a = [1, 2, 3, 4] b = [5, 6, 7, 8] lists = [a, b] # or directly -> lists = [ [1, 2, 3, 4], [5, 6, 7, 8] ] new_dict = {} for idx, sublist in enumerate([a, b]): # or enumerate(lists) new_dict[idx] = sublist

Espero eso ayude


Una solución de pandas :

Preparar:

import pandas as pd a = [0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 4, 4, 4] b = pd.np.random.randint(0, 100, len(a)).tolist() >>> b Out[]: [28, 68, 71, 25, 25, 79, 30, 50, 17, 1, 35, 23, 52, 87, 21] df = pd.DataFrame(columns=[''Group'', ''Value''], data=list(zip(a, b))) # Create a dataframe >>> df Out[]: Group Value 0 0 28 1 0 68 2 0 71 3 1 25 4 1 25 5 1 79 6 1 30 7 1 50 8 2 17 9 2 1 10 2 35 11 3 23 12 4 52 13 4 87 14 4 21

Solución:

>>> df.groupby(''Group'').Value.apply(list).to_dict() Out[]: {0: [28, 68, 71], 1: [25, 25, 79, 30, 50], 2: [17, 1, 35], 3: [23], 4: [52, 87, 21]}

Tutorial:

  1. cree un pd.DataFrame partir de las listas de entrada, a se llama Group b llama Value
  2. df.groupby(''Group'') crea grupos basados ​​en a
  3. .Value.apply(list) obtiene los valores para cada grupo y lo convierte en list
  4. .to_dict() convierte el DataFrame resultante en dict

Sincronización:

Para tener una idea de los tiempos para un conjunto de prueba de 1,000,000 valores en 100,000 grupos:

a = sorted(np.random.randint(0, 100000, 1000000).tolist()) b = pd.np.random.randint(0, 100, len(a)).tolist() df = pd.DataFrame(columns=[''Group'', ''Value''], data=list(zip(a, b))) >>> df.shape Out[]: (1000000, 2) %timeit df.groupby(''Group'').Value.apply(list).to_dict() 4.13 s ± 9.29 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Pero para ser honesto, es probable que sea menos eficiente que itertools.groupby sugirió @RomanPerekhrest, o defaultdict sugirió por @ Ajax1234.


itertools.groupby() alternativa de itertools.groupby() :

import itertools a = [0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3] b = [24, 53, 88, 32, 45, 24, 88, 53, 11, 22, 33, 44, 55, 66, 77] result = { k: [i[1] for i in g] for k,g in itertools.groupby(sorted(zip(a, b)), key=lambda x:x[0]) } print(result)

La salida:

{0: [24, 53, 88], 1: [24, 32, 45, 53, 88], 2: [11, 22, 33, 44, 55, 66], 3: [77]}