首页 > 解决方案 > 如何有效地将多个字典的共享键子集作为多个数组?

问题描述

有没有一种有效的方法来获取多个字典(的键)的交集?

类似于迭代两个字典中的共享键,除了想法不是迭代而是获取集合,因此它可以用于获取字典的子集。

d1 = {'a':[1,2], 'b':[2,2]}
d2 = {'e':[3,2], 'b':[5,1], 'a':[5,5]}
d3 = {'b':[8,2], 'a':[3,3], 'c': [1,2]}

所以手动交叉很简单

d1.keys() & d2.keys() & d3.keys()

但是n维列表呢?我觉得有比这更好的方法:

d_list = [d1, d2, d3]

inter_keys = {}
for i in range(len(d_list)):
    if i == 0:
        inter_keys = d_list[i]
    inter_keys = inter_keys & d_list[i].keys() 

然后得到一个子集

subsets = []
for n in d_list:
    subsets.append( {k: n[k] for k in inter_keys} )

最后用它来获取值子集

v = [ x.values() for x in subsets ]

[[[2 2] [1 2]]

[[5 1] [5 5]]

[[8 2] [3 3]]]

我在想可能有一种方法可以使用 numpy 之类的方法where来更有效地获取子集,但不确定。

标签: pythonnumpydictionary

解决方案


我认为您的代码可以简化为:

In [383]: d_list=[d1,d2,d3]
In [388]: inter_keys = d_list[0].keys()
In [389]: for n in d_list[1:]:
     ...:     inter_keys &= n.keys()
     ...: 
In [390]: inter_keys
Out[390]: {'a', 'b'}
In [391]: np.array([[n[k] for k in inter_keys] for n in d_list])
Out[391]: 
array([[[1, 2],
        [2, 2]],

       [[5, 5],
        [5, 1]],

       [[3, 3],
        [8, 2]]])

即迭代获取键的交集,然后将值提取到列表的列表中,可以将其制成数组。

inter_keys开始是一个dict.keys对象,但变成了set; 两者都与&=.

我认为没有办法绕过以dict索引n[k]为核心的双循环。除非您可以使用valuesoritems列表,否则无法dict逐个访问项目。

sub_sets列表dict是不必要的中间步骤。

所有键和值都可以提取到列表列表中,但这无助于选择公共子集:

In [406]: big_list = [list(d.items()) for d in d_list]
In [407]: big_list
Out[407]: 
[[('a', [1, 2]), ('b', [2, 2])],
 [('e', [3, 2]), ('b', [5, 1]), ('a', [5, 5])],
 [('b', [8, 2]), ('a', [3, 3]), ('c', [1, 2])]]

推荐阅读