Python 基于另一个dict的值筛选dict列表

Python 基于另一个dict的值筛选dict列表,python,python-3.x,Python,Python 3.x,我有一个字典列表、一组键和另一个要比较的字典 如果三个可能键中任意两个的值与dict\u to\u compare中的值匹配,我需要过滤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'},

我有一个字典列表、一组键和另一个要比较的字典

如果三个可能键中任意两个的值与
dict\u to\u compare
中的值匹配,我需要过滤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'}
]
 out = [{'k1': 'val1', 'k2': 'val2', 'k3': 'val3'}] #First element from list
输出:

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
  • 目录列表中的所有元素都有相同的键
  • dict\u to\u compare
    的键也与dict的
    list\u的元素相同
  • 可以匹配目录列表中的多个元素
  • 两个键的任何组合的值都应该匹配,而不是所有三个键
我尝试通过显式指定一组
if
elif
条件来实现这一点。但问题是,这套钥匙实在太大了。有没有更好的办法解决这个问题


谢谢

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

您可以使用具有所需过滤方案的列表理解重新创建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'}]

我不知道我是否理解你的需要,但这是我的机会:

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]

我的答案与这里的大多数答案相似

我建议您使用自定义函数,在达到所需匹配计数时停止比较键。因为你提到你有很多钥匙要比较,这将是有益的

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

out=[d代表dict if sum列表中的d([dict\u to\u compare[k]==d[k]代表dict\u to\u compare中的k])>1]
很抱歉,我错过了关于两场比赛而不是三场比赛的最后一点(似乎我不是唯一一个)。只需将我上面评论中的
>1
更改为
==2
,就可以了。或者您也可以类似地修改下面的一个答案。既然您正在进行成员资格测试以检查条件并转换到
列表
,为什么不转换到
,这样会更快?现在看起来更干净了+1OP表示至少2次,而不是最多1次失败。我会选择
>1