基于另一个字典的值过滤字典列表

9
我是一位可以翻译文本的助手。
我有一个字典列表list_of_dict,一个键集合set_of_keys和另一个字典dict_to_compare
如果任意两个可能的键的值与来自dict_to_compare的值匹配,则需要过滤字典列表。 输入:
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条件来完成这个任务。但问题是键集非常庞大。有更好的解决方法吗?

谢谢


out = [d for d in list_of_dict if sum([dict_to_compare[k] == d[k] for k in dict_to_compare]) > 1] - pault
抱歉,我错过了关于两个匹配项而不是三个的最后一点(似乎我不是唯一一个)。只需将我上面评论中的“>1”更改为“==2”,那应该就可以了。或者您也可以类似地修改下面的答案之一。 - pault
4个回答

8
您可以使用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'}]

既然您正在执行成员测试以检查条件并转换为list,为什么不转换为set呢?这样会更快。 - Ma0
现在看起来更干净了。+1 - Ma0

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'}]

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]

OP说至少2个,而不是最多1个失败。我会选择>1 - Ma0

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) 
]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接