我有两个清单:
a = [0, 0, 0, 1, 1, 1, 1, 1, .... 99999]
b = [24, 53, 88, 32, 45, 24, 88, 53, ...... 1]
我想将这两个列表合并到一个字典中:
{
0: [24, 53, 88],
1: [32, 45, 24, 88, 53],
......
99999: [1]
}
解决方案可能正在使用for
循环,这看起来并不优雅,如:
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]]
虽然这确实有效,但效率很低,而且当列表非常大时会占用太多时间。我想知道更优雅的方法来构建这样的字典吗?
提前致谢!
答案 0 :(得分:30)
您可以使用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))
输出:
{0: [24, 53, 88], 1: [32, 45, 24, 88, 53], 9999: [1]}
答案 1 :(得分:13)
替代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)
输出:
{0: [24, 53, 88], 1: [24, 32, 45, 53, 88], 2: [11, 22, 33, 44, 55, 66], 3: [77]}
答案 2 :(得分:5)
没有奇特的结构,只是一个简单的结构。字典。
d = {}
for x, y in zip(a, b):
d.setdefault(x, []).append(y)
答案 3 :(得分:4)
你可以用dict理解来做到这一点:
counts = {"worm": 0, "guest": 0, "anonymous": 0}
for line in myfile:
for word in counts:
if word in line:
counts[word] += 1
奇怪的是,你似乎无法使用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]}
来完成这项工作,因为这会将所有键的值设置为等于相同的空数组:
dict.fromkeys(set(list_a), [])
答案 4 :(得分:3)
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
,a
称为Group
,b
称为Value
df.groupby('Group')
根据a
.Value.apply(list)
获取每个组的值并将其转换为list
.to_dict()
会将生成的DataFrame
转换为dict
了解100,000个组中1,000,000个值的测试集的时间安排:
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)
但说实话,它可能不如@RomanPerekhrest建议的itertools.groupby
或@ Ajax1234建议的defaultdict
效率低。
答案 5 :(得分:2)
也许我错过了这一点,但至少我会尽力帮助。如果你必须列出并希望将它们放入dict中,请执行以下操作
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
希望有所帮助
答案 6 :(得分:0)
或者事先进行字典理解,然后由于所有键都具有空列表的值,因此要遍历两个列表的zip
,然后将第二个列表的值添加到字典的键中以命名第一个列表的值,否由于预先的字典理解,需要try-except子句(或if语句)来查看键是否存在:
d={k:[] for k in l}
for x,y in zip(l,l2):
d[x].append(y)
现在:
print(d)
是:
{0: [24, 53, 88], 1: [32, 45, 24, 88, 53], 9999: [1]}