如何从多个具有重复值的列表中创建嵌套字典?

时间:2019-09-07 11:14:10

标签: python list dictionary

假设一组三个列表:

val = [1 2 2 3 5 5 5 6 8]
m = ['m2' 'm1' 'm2' 'm2' 'm1' 'm2' 'm2' 'm1' 'm1']
v = ['v9' 'v3' 'v7' 'v5' 'v1' 'v6' 'v8' 'v2' 'v4']

我正在尝试创建一个嵌套字典,其中val中的每个元素都用作一阶键。 m中的元素应描述二阶密钥。

我已经找到了如何使用来创建嵌套字典

d = {}
for x, y, z in zip(val, m, v):
    d.setdefault(x,{})[y] = []

创建以下结构

{1: {'m2': []}, 2: {'m2': [], 'm1': []}, 3: {'m2': []}, 5: {'m2': [], 'm1': []}, 6: {'m1': []}, 8: {'m1': []}}

如果我在z后面加上

d.setdefault(x,{})[y].append(z)

我得到

{1: {'m2': ['v9']}, 2: {'m2': ['v7'], 'm1': ['v3']}, 3: {'m2': ['v5']}, 5: {'m2': ['v8'], 'm1': ['v1']}, 6: {'m1': ['v2']}, 8: {'m1': ['v4']}} 

我也知道如何创建一个字典,将v的元素分配给相应的一阶键(即val的元素)

for elem in range(len(val)):
    if val[elem] not in d:
        d[val[elem]] = []
    d[val[elem]].append(v[elem])

导致

{1: ['v9'], 2: ['v3', 'v7'], 3: ['v5'], 5: ['v1', 'v6', 'v8'], 6: ['v2'], 8: ['v4']}

但是我看不到获得所需输出的最后一步:

{1: {'m2': ['v9']}, 2: {'m2': ['v7'], 'm1': ['v3']}, 3: {'m2': ['v5']}, 5: {'m2': ['v6', 'v8'], 'm1': ['v1']}, 6: {'m1': ['v2']}, 8: {'m1': ['v4']}}

(子字典中缺少键“ 5”和二阶键“ m2”的元素“ v6”(即5:{'m2':['v8']})

2 个答案:

答案 0 :(得分:1)

itertools.groupbyzip用于嵌套的字典理解。

示例

from itertools import groupby

val = [1, 2, 2, 3, 5, 5 ,5, 6, 8]
m = ['m2', 'm1', 'm2' ,'m2', 'm1', 'm2', 'm2', 'm1' ,'m1']
v = ['v9', 'v3' ,'v7', 'v5', 'v1', 'v6', 'v8', 'v2', 'v4']    

f1 = lambda x: x[:2]
f2 = lambda x: x[0]

print({k: {x[1]: [z[2] for z in y] for x, y in groupby(sorted(g, key=f1), f1)} for k, g in groupby(sorted(zip(val, m, v), key=f2), key=f2)})

# {1: {'m2': ['v9']}, 2: {'m1': ['v3'], 'm2': ['v7']}, 3: {'m2': ['v5']}, 5: {'m1': ['v1'], 'm2': ['v6', 'v8']}, 6: {'m1': ['v2']}, 8: {'m1': ['v4']}}

答案 1 :(得分:1)

尝试使用defaultdict

from collections import defaultdict

val = [1, 2, 2, 3, 5, 5, 5, 6, 8]
m = ['m2', 'm1', 'm2', 'm2', 'm1', 'm2', 'm2', 'm1', 'm1']
v = ['v9', 'v3', 'v7', 'v5', 'v1', 'v6', 'v8', 'v2', 'v4']

dd = defaultdict(lambda: defaultdict(list))

for k1, k2, k3 in zip(val, m, v):
    dd[k1][k2].append(k3)

dd