简体   繁体   English

Python-根据键值是否包含另一个列表中的所有项来过滤字典列表

[英]Python - Filter list of dictionaries based on if key value contains all items in another list

I have a list of dictionaries that looks like this, but with around 500 items: 我有一个看起来像这样的字典列表,但是有大约500个条目:

listOfDicts = [{'ID': 1, 'abc': {'123': 'foo'}}, ... {'ID': 7, 'abc': {'123':'foo','456': 'bar'}}]

sampleFilterList = ['123', '456']

I am trying to filter the listOfDicts for all the results where all the values in the sampleFilterList are in the key 'abc' 我正在尝试为所有结果过滤listOfDicts,其中sampleFilterList中的所有值都在键“ abc”中

The result should be a list: 结果应该是一个列表:

[{'ID': 7, 'abc': {'123':'foo','456': 'bar'}}, ...]

I tried [i for i in listOfDicts if a for a in sampleFilterList in i['abc']] , but I am getting an UnboundLocalError: local variable 'a' referenced before assignment 我试过[i for i in listOfDicts if a for a in sampleFilterList in i['abc']] ,我却遇到了UnboundLocalError: local variable 'a' referenced before assignment

You need to move the in condition test before the for keyword in the list comprehension and also use get will be more safe, which returns a default value instead of throwing an error, if you are not sure if all the dictionaries in the list have the keyword abc : 您需要在移动状态下测试的关键字列表中的理解,还可以使用get将更加安全,它返回默认值,而不是抛出一个错误,如果你不知道,如果在列表中的所有词典中有关键字abc

listOfDicts = [{'ID': 1, 'abc': {'123': 'foo'}}, {'ID': 7, 'abc': {'123':'foo','456': 'bar'}}]    ​
sampleFilterList = ['123', '456']

[d for d in listOfDicts if all(s in d.get('abc', {}) for s in sampleFilterList)]
# [{'ID': 7, 'abc': {'123': 'foo', '456': 'bar'}}]

Or if use a set as of @DYZ, you can use issubset : 或者,如果使用@DYZ的集合,则可以使用issubset

filterSet = set(sampleFilterList)
[d for d in listOfDicts if filterSet.issubset(d.get('abc', {}))]
# [{'ID': 7, 'abc': {'123': 'foo', '456': 'bar'}}]

First, convert your second list to a set for more efficient comparisons: 首先,将第二个列表转换为一组,以进行更有效的比较:

sampleFilterSet = set(sampleFilterList)

Now, compare the 'abc' keys for each list item to the aforesaid set: 现在,将每个列表项的“ abc”键与上述设置进行比较:

[item for item in listOfDicts if not (sampleFilterSet - item['abc'].keys())]    
#[{'ID': 7, 'abc': {'123': 'foo', '456': 'bar'}}]

This is the fastest solution. 这是最快的解决方案。 A more Pythonic (but somewhat slower) solution is to use filter() : 一种更Pythonic(但速度稍慢)的解决方案是使用filter()

list(filter(lambda item: not (sampleFilterSet - item['abc'].keys()), listOfDicts))
#[{'ID': 7, 'abc': {'123': 'foo', '456': 'bar'}}]

Here is a working version with nested list comprehensions. 这是具有嵌套列表理解的工作版本。 Your problem is that the a for a in... is a list comprehension, and needs to be used in constructing a new list. 您的问题是a for a in...的a是列表理解,需要在构造新列表时使用。

[i for i in listOfDicts if [a for a in sampleFilterList if a in i['abc']] == sampleFilterList]
for i in zip(listOfDicts):
 a = i[0]['abc']
 print (a)

or: 要么:

for i in zip(listOfDicts):
    if 'abc' in i[0]:
        a = i
        print (a)

This is an elegant way to do it, I hope it will be useful. 这是一种优雅的方法,希望它会有用。

You could try the following one-liner: 您可以尝试以下单线:

passed_the_filter = [[dictionary_entry for dictionary_entry in list_of_dicts if filter_test in dictionary_entry['abc']] for filter_test in filter]

It is a nested list comprehension that iterates through both the filter and the dictionary list. 这是一个嵌套列表理解,它遍历过滤器和字典列表。 It checks if the filter is a key in the dictionary entries' "abc" value. 它检查过滤器是否是字典条目的“ abc”值中的键。 Your problem was that you used the wrong list comprehension syntax. 您的问题是您使用了错误的列表理解语法。


NB You may want to note that you might not be sure that an element has a "abc" key! 注意:您可能要注意,您可能不确定元素是否具有“ abc”键!


Thank you for reading this. 谢谢您阅读此篇。

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

相关问题 python 根据键值过滤字典列表 - python filter list of dictionaries based on key value 基于 Python 中的键(不是键值)过滤字典列表 - Filter a list of dictionaries based on key (not key value) in Python 根据键/值条件过滤 Python 字典列表 - Filter Python list of dictionaries based on key/value criteria 根据键的值过滤字典列表 - Filter list of dictionaries based on the value of a key 根据键过滤Python中的词典列表 - Filter a list of dictionaries in Python based on key 根据另一个密钥过滤字典列表以删除密钥中的重复项 - Filter a list of dictionaries to remove duplicates within a key, based on another key 根据字典列表中的另一个值(键的)检索键的值 - Retrieve a value of a key based on another value(of key) in the list of dictionaries 根据基于该字典中另一个键的值的条件,更新python词典列表中的值 - Update a value in a list of dictionaries in python based on a condition based on the value of another key in that dictionary 有没有办法根据一个字典中的值小于另一个字典中的相同键来过滤字典列表? - Is there a way to filter a list of dictionaries based on a value in one dictionary being less than the same key in another? 通过基于另一个键的值组合on键的值来获取字典列表 - get list of dictionaries by combining values of on key based on value of another key
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM