根据另一个词典中的值过滤dict列表

时间:2017-11-28 15:54:50

标签: python python-3.x

我有一个词典列表list_of_dict,一组键set_of_keys和另一个词典dict_to_compare

如果三个可能的键中任意两个键的值与dict_to_compare的值匹配,我需要过滤dicts列表。

输入:

set_of_keys = {'val1', 'val2', 'val3'}

dict_to_compare = {'k1': 'val1', 'k2': 'val2','k3':'val6'}

list_of_dict = [
        {'k1': 'val1', 'k2': 'val2', 'k3':'val3'},
        {'k1': 'val4', 'k2': 'val5', 'k3':'val6'},
        {'k1': 'val7', 'k2': 'val8', 'k3':'val9'}
]

输出:

 out = [{'k1': 'val1', 'k2': 'val2', 'k3': 'val3'}] #First element from list
  • list_of_dicts中的所有元素都有相同的键。
  • dict_to_compare也具有与list_of_dicts
  • 元素相同的键
  • 可以匹配list_of_dicts中的多个元素。
  • 两个键的任意组合的值不应与三个键匹配。

我尝试通过明确指定一堆if elif条件来做到这一点。但问题是关键设置确实很大。有没有更好的方法来解决这个问题?

由于

4 个答案:

答案 0 :(得分:7)

您可以使用sum

dict_to_compare = {'k1': 'val1', 'k2': 'val2','k3':'val6'}
set_of_keys = {'val1', 'val2', 'val3'}
list_of_dict = [
    {'k1': 'val1', 'k2': 'val2', 'k3':'val3'},
    {'k1': 'val4', 'k2': 'val5', 'k3':'val6'},
    {'k1': 'val7', 'k2': 'val8', 'k3':'val9'}
]
final_list = [i for i in list_of_dict if sum(c in set_of_keys for c in i.values()) >= 2]

输出:

[{'k3': 'val3', 'k2': 'val2', 'k1': 'val1'}]

答案 1 :(得分:5)

您可以使用具有所需过滤方案功能的列表理解来重新创建list_of_dict

set_of_keys = {'val1', 'val2', 'val3'}

dict_to_compare = {'k1': 'val1', 'k2': 'val2','k3':'val6'}

list_of_dict = [
        {'k1': 'val1', 'k2': 'val2', 'k3':'val3'},
        {'k1': 'val4', 'k2': 'val5', 'k3':'val6'},
        {'k1': 'val7', 'k2': 'val8', 'k3':'val9'}
]

list_of_dict = [d for d in list_of_dict if sum(1 for k, v in d.items() if dict_to_compare.get(k, None)==v)>1]
print(list_of_dict)  # -> [{'k1': 'val1', 'k2': 'val2', 'k3': 'val3'}]

答案 2 :(得分:1)

我不知道我是否明白你需要什么,但这是我的镜头:

result = [i for i in list_of_dict if len([j for j in i.values() if j in dict_to_compare.values()]) == len(set_of_keys) - 1]

答案 3 :(得分:1)

我的答案与此处的大多数答案类似。

我建议您使用自定义功能,在达到所需的匹配计数时停止比较键。既然你提到你有很多要比较的关键,这将是有益的。

def my_sum(gen,count_needed):
    for e in gen:                 #gen is a generator
        if e:                     #e is true when keys match
            count_needed -= 1
            if count_needed==0:   #stop comparison when desired no.of matches is found
                return True
    return False


count_needed = 2
out = [ d for d in list_of_dict
        if my_sum( (d[key] == dict_to_compare[key] for key in d) ,count_needed) 
]