简体   繁体   English

过滤字典中的常见子字典键

[英]Filter common sub-dictionary keys in a dictionary

How do i filter all common sub dictionary keys that exists in other sub dictionary keys in the parent dictionary 如何过滤父词典中其他子词典键中存在的所有常用子词典键

d = {
  '0': {'key_x': 0, 'key_y': 15, 'key_z': 41}
  '1': {'key_x': 5, 'key_y': 22}
  '2': {'key_x': 6, 'key_y': 41}
}

result ['key_x', 'key_y']

current solution is 目前解决方案是

intersect = {}
for k in corner_values.keys():
    for j in corner_values[k]:
        if j not in intersect:
            intersect[j] = 1
        else:
            intersect[j] += 1

for k in intersect:
    if intersect[k] != len(corner_values.keys()):
        del intersect[k]

Is there any simpler solution for this? 有没有更简单的解决方案呢?

You can map the dictionaries to set and then reduce using set.intersection : 您可以mapset的词典,然后使用set.intersection reduce

>>> from functools import reduce # if you are using Python 3
>>> d = {                       
...   '0': {'key_x': 0, 'key_y': 15, 'key_z': 41},
...   '1': {'key_x': 5, 'key_y': 22},
...   '2': {'key_x': 6, 'key_y': 41}
... }
>>> reduce(set.intersection, map(set, d.values()))
{'key_x', 'key_y'}

Note: In Python 3, reduce has been moved to functools . 注意:在Python 3中, reduce已移至functools

Update: As seen in @John's answer , set.intersection can handle an arbitrary number of sets, so the reduce is not even necessary. 更新:如@ John的回答所示set.intersection可以处理任意数量的集合,因此甚至不需要reduce Just set.intersection(*map(set, d.values())) 只需set.intersection(*map(set, d.values()))

You can do a single set.intersection operation once you extract all the keys. 提取所有密钥后,您可以执行单个set.intersection操作。 It's a one-liner then: 这是一个单线然后:

set.intersection(*(set(x) for x in d.itervalues()))

Breaking that down, the first part evaluated is this: 打破这一点,第一部分评估是这样的:

(set(x) for x in d.itervalues())

That's a generator which produces: 这是一个产生的发电机:

{'key_x', 'key_y'}, {'key_x', 'key_y', 'key_z'}, {'key_x', 'key_y'}

In Python 3 that generator is equivalent to: 在Python 3中,该生成器相当于:

map(set, d.values())

But in Python 2, map is less efficient because it constructs a list that we don't need (as does values() instead of itervalues() ). 但是在Python 2中, map的效率较低,因为它构造了一个我们不需要的listvalues()而不是itervalues() )。

In any case, the results of that generator are passed to set.intersection (using the * argument unpacker) to do the heavy lifting in a single call. 在任何情况下,该生成器的结果都会传递给set.intersection (使用*参数解包器),以便在单个调用中完成繁重的工作。

An alternative with pandas , the keys do not need to be ordered: 使用pandas的替代方案,不需要订购密钥:

import pandas as pd

list(pd.DataFrame(d).dropna().index)

#['key_x', 'key_y']

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM