如何通过另一个字典过滤python字典?

时间:2015-06-05 08:38:17

标签: python dictionary

我想创建一个方法,查看mainDict中的每个值,返回包含filterDict中列出的所有键值对的所有值的数组。

def where(mainDicts, filterDict):
    pass

mydicts = [{'title': "title 1", 'author': "author 1", 'year': 1611},
           {'title': "title 2", 'author': "author 2", 'year': 1615},
           {'title': "title 3", 'author': "author 1", 'year': 1611}]

filterDict = {'year': 1611, 'author': "author 1"}

where(mydicts, filterDict)

我想要归还:

[{'title': "title 1", 'author': "author 1", 'year': 1611},
 {'title': "title 3", 'author': "author 1", 'year': 1611}]

4 个答案:

答案 0 :(得分:2)

假设您运行Python 3:

django_fixtures

引用文档:

  

键视图设置类似,因为它们的条目是唯一且可清除的。   如果所有值都是可清除的,那么def where(mainDicts, filterDict): return [x for x in mainDicts if not filterDict.items() - x.items()] 对是唯一的   hashable,那么items视图也是类似的。对于类似于集合的视图,可以使用为抽象基类 collections.abc.Set 定义的所有操作(例如,(key, value)==或{{1 }})。

有关详细信息,请参阅Dictionary view objects。 如果您需要在Python 2中使用它,只需将<替换为viewitems()

示例:

^

请注意,如果您的值不可播放,则上述操作无效(请参阅Glossary),但以下内容

items()

答案 1 :(得分:1)

只需使用列表推导,每个项d检查k中的所有键filterDict是否都在该项中,如果是,则{{1}是否值是一样的。

v

这也适用于Python 2.示例:

def where(mainDict, filterDict):
    return [d for d in mainDict if all(k in d and d[k] == v 
                                       for k, v in filterDict.items())]

答案 2 :(得分:0)

作为一种更加pythonic的方式,您可以使用dict.viewitems来获取词典和过滤器词典之间的交集,那么如果交叉点与过滤器相等,则可以返回它:

>>> filt={'author': 'author 1', 'year': 1611}
>>> [d for d in mydict if dict(filt.viewitems()&d.viewitems())==filt]
[{'author': 'author 1', 'year': 1611, 'title': 'title 1'}, {'author': 'author 1', 'year': 1611, 'title': 'title 3'}]

详细了解字典视图对象https://docs.python.org/2/library/stdtypes.html#dictionary-view-objects

答案 3 :(得分:0)

这是另一种方法,也许它对你来说更具可读性。它的python 2和3兼容并非常直接。

def where(list_of_dicts, filterDict):

    result = [] # to be returned, a list of dicts

    for d in list_of_dicts:
        n = 0 # count how many key/value pairs matches with filterDict
        for key in filterDict:
            try: # in case key is missing
                if d[key] == filterDict[key]:
                    n += 1
            except:
                pass # change with a proper error message
        if n == len(filterDict): # if True then all the key/value pairs in filterDict are in d
            result.append(d)

    return result




mydicts = [{'title': "title 1", 'author': "author 1", 'year': 1611},
          {'title': "title 2", 'author': "author 2", 'year': 1615},
          {'title': "title 3", 'author': "author 1", 'year': 1611}]

filterDict = {'year': 1611, 'author': "author 1"}


a = where(mydicts, filterDict)
print(a)

打印出来:

[{'author': 'author 1', 'year': 1611, 'title': 'title 1'}, {'author': 'author 1', 'year': 1611, 'title': 'title 3'}]