python - 如何有效地将多个字典的共享键子集作为多个数组?
问题描述
有没有一种有效的方法来获取多个字典(的键)的交集?
类似于迭代两个字典中的共享键,除了想法不是迭代而是获取集合,因此它可以用于获取字典的子集。
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 ]
- 实际上,最后一部分被格式化为
v = np.array([ np.array(list(x.values())) for x in subsets ])
将 ndarray 设置为:
[[[2 2] [1 2]]
[[5 1] [5 5]]
[[8 2] [3 3]]]
我在想可能有一种方法可以使用 numpy 之类的方法where
来更有效地获取子集,但不确定。
解决方案
我认为您的代码可以简化为:
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]
为核心的双循环。除非您可以使用values
oritems
列表,否则无法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])]]
推荐阅读
- r - 我可以将 depmixs4 用于多个主题吗?
- python - Selenium Xpath,有人可以帮我解决这个 find.element
- javascript - 使用 UTC 格式日期作为过滤器查询 mongodb
- c++ - 为什么我的 Vscode IDE 在我运行 C++ 程序时出现奇怪的错误消息
- r - 如何在 r 中指定日期格式?
- spring - Spring Cloud 版本 2020.0.0 的云启动器引导依赖项
- c++ - 获取向量中唯一元素的索引
- stored-procedures - 试图从雪花中的过程返回变量值。它正在出错
- http - 我如何在 Parasoft SOATest 的响应对象中引用从邮递员发送的请求标头/正文元数据?
- elasticsearch - 使用 Heartbeat 的弹性正常运行时间监视器——kibana 中缺少几个监视器