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:
- cree un
pd.DataFrame
partir de las listas de entrada,a
se llamaGroup
b
llamaValue
-
df.groupby(''Group'')
crea grupos basados ena
-
.Value.apply(list)
obtiene los valores para cada grupo y lo convierte enlist
-
.to_dict()
convierte elDataFrame
resultante endict
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]}