J'ai deux listes:
a = [0, 0, 0, 1, 1, 1, 1, 1, .... 99999]
b = [24, 53, 88, 32, 45, 24, 88, 53, ...... 1]
Je veux fusionner ces deux listes dans un dictionnaire comme:
{
0: [24, 53, 88],
1: [32, 45, 24, 88, 53],
......
99999: [1]
}
Une solution pourrait utiliser la boucle for
, qui n'a pas l'air bonne et élégante, comme:
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]]
Bien que cela fonctionne, il est inefficace et prendrait trop de temps lorsque la liste est extrêmement longue. Je veux savoir des façons plus élégantes de construire un tel dictionnaire?
Merci d'avance!
Vous pouvez utiliser 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))
Sortie:
{0: [24, 53, 88], 1: [32, 45, 24, 88, 53], 9999: [1]}
Alternative itertools.groupby()
solution:
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)
Le résultat:
{0: [24, 53, 88], 1: [24, 32, 45, 53, 88], 2: [11, 22, 33, 44, 55, 66], 3: [77]}
Pas de structures fantaisistes, juste un vieux dictionnaire.
d = {}
for x, y in Zip(a, b):
d.setdefault(x, []).append(y)
Vous pouvez le faire avec une compréhension dictée:
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]}
Curieusement, vous ne pouvez pas sembler fonctionner avec dict.fromkeys(set(list_a), [])
car cela va définir la valeur de toutes les clés égale au tableau same empty:
my_dict = dict.fromkeys(set(list_a), []) # my_dict = {0: [], 1: []}
my_dict[0].append(1) # my_dict = {0: [1], 1: [1]}
Une solution pandas
:
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
>>> 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]}
pd.DataFrame
à partir des listes d'entrées, a
est appelé Group
et b
appelé Value
df.groupby('Group')
crée des groupes basés sur a
.Value.apply(list)
récupère les valeurs de chaque groupe et le transforme en list
.to_dict()
convertit la DataFrame
résultante en dict
Pour avoir une idée des temps pour un ensemble de test de 1 000 000 de valeurs sur 100 000 groupes:
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)
Mais pour être honnête, il est probablement moins efficace que itertools.groupby
suggéré par @RomanPerekhrest ou defaultdict
suggéré par @ Ajax1234.
Peut-être que je manque le point, mais au moins je vais essayer d'aider. Si vous avez des listes et que vous voulez les mettre dans le dict, procédez comme suit:
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
j'espère que ça aide
Ou bien faites la compréhension du dictionnaire auparavant, puis puisque toutes les clés sont là avec des valeurs de listes vides, parcourez la variable Zip
des deux listes, puis ajoutez la valeur de la deuxième liste à la valeur de la première liste du dictionnaire, pas besoin de clause try-except ( ou if)), pour voir si la clé existe ou non, à cause de la compréhension préalable du dictionnaire:
d={k:[] for k in l}
for x,y in Zip(l,l2):
d[x].append(y)
À présent:
print(d)
Est:
{0: [24, 53, 88], 1: [32, 45, 24, 88, 53], 9999: [1]}