Python-基于关键字值是否包含另一个列表中的所有项筛选字典列表
我有一个字典列表,看起来像这样,但有大约500个条目:Python-基于关键字值是否包含另一个列表中的所有项筛选字典列表,python,list,dictionary,Python,List,Dictionary,我有一个字典列表,看起来像这样,但有大约500个条目: listOfDicts = [{'ID': 1, 'abc': {'123': 'foo'}}, ... {'ID': 7, 'abc': {'123':'foo','456': 'bar'}}] sampleFilterList = ['123', '456'] 我正在尝试筛选列表中的所有结果,其中sampleFilterList中的所有值都位于键“abc”中 结果应该是一个列表: [{'ID': 7, 'abc': {'123':'
listOfDicts = [{'ID': 1, 'abc': {'123': 'foo'}}, ... {'ID': 7, 'abc': {'123':'foo','456': 'bar'}}]
sampleFilterList = ['123', '456']
我正在尝试筛选列表中的所有结果,其中sampleFilterList中的所有值都位于键“abc”中
结果应该是一个列表:
[{'ID': 7, 'abc': {'123':'foo','456': 'bar'}}, ...]
我尝试了[I for I in listofdics if a for a in sampleFilterList in I['abc']]
,但是我得到了一个未绑定的局部错误:在赋值之前引用了局部变量“a”
您需要在列表理解中的for关键字之前移动in-condition测试,并且使用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'}}]
或者,如果使用@DYZ的集合,则可以使用issubset
:
filterSet = set(sampleFilterList)
[d for d in listOfDicts if filterSet.issubset(d.get('abc', {}))]
# [{'ID': 7, 'abc': {'123': 'foo', '456': 'bar'}}]
如果不确定列表中的所有词典是否都有关键字abc,则需要在列表中的for关键字之前移动in-condition测试,并使用get
将更安全,它将返回默认值而不是抛出错误:
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'}}]
或者,如果使用@DYZ的集合,则可以使用issubset
:
filterSet = set(sampleFilterList)
[d for d in listOfDicts if filterSet.issubset(d.get('abc', {}))]
# [{'ID': 7, 'abc': {'123': 'foo', '456': 'bar'}}]
首先,将第二个列表转换为一个集合,以便进行更有效的比较:
sampleFilterSet = set(sampleFilterList)
现在,将每个列表项的“abc”键与上述设置进行比较:
[item for item in listOfDicts if not (sampleFilterSet - item['abc'].keys())]
#[{'ID': 7, 'abc': {'123': 'foo', '456': 'bar'}}]
这是最快的解决方案。一个更具python风格(但速度稍慢)的解决方案是使用filter()
:
首先,将第二个列表转换为一个集合,以便进行更有效的比较:
sampleFilterSet = set(sampleFilterList)
现在,将每个列表项的“abc”键与上述设置进行比较:
[item for item in listOfDicts if not (sampleFilterSet - item['abc'].keys())]
#[{'ID': 7, 'abc': {'123': 'foo', '456': 'bar'}}]
这是最快的解决方案。一个更具python风格(但速度稍慢)的解决方案是使用filter()
:
这是一个嵌套列表理解的工作版本。您的问题是,
a for a in…
是一个列表理解,需要在构建新列表时使用
[i for i in listOfDicts if [a for a in sampleFilterList if a in i['abc']] == sampleFilterList]
这是一个嵌套列表理解的工作版本。您的问题是,
a for a in…
是一个列表理解,需要在构建新列表时使用
[i for i in listOfDicts if [a for a in sampleFilterList if a in i['abc']] == sampleFilterList]
或:
这是一种优雅的方式,我希望它会有用
或:
这是一种优雅的方法,我希望它会有用。您可以尝试以下一种方法:
passed_the_filter = [[dictionary_entry for dictionary_entry in list_of_dicts if filter_test in dictionary_entry['abc']] for filter_test in filter]
它是一个嵌套的列表理解,可以遍历过滤器和字典列表。它检查过滤器是否是字典条目“abc”值中的键。您的问题是使用了错误的列表理解语法
注意:您可能需要注意,您可能不确定某个元素是否有“abc”键
感谢您阅读此文章。您可以尝试以下一行:
passed_the_filter = [[dictionary_entry for dictionary_entry in list_of_dicts if filter_test in dictionary_entry['abc']] for filter_test in filter]
它是一个嵌套的列表理解,可以遍历过滤器和字典列表。它检查过滤器是否是字典条目“abc”值中的键。您的问题是使用了错误的列表理解语法
注意:您可能需要注意,您可能不确定某个元素是否有“abc”键
谢谢阅读。
考虑删除结果列表中的第二个项目,因为它不清楚它来自哪里。考虑删除结果列表中的第二个项目,因为它不清楚它来自哪里。如果项目(ABC)中的键还有其他值不在SAMPLE FielTSET中呢?例如,如果它包含5个键,其中2个在集合中?谢谢,它可以工作!如果不是陈述的一部分,你介意解释一下吗?是否正在检查所有样本集是否都在项['abc'].keys()中?如果项['abc']中的键也有其他不在样本过滤器集中的值,该怎么办?例如,如果它包含5个键,其中2个在集合中?谢谢,它可以工作!如果不是陈述的一部分,你介意解释一下吗?是否正在检查所有样本集是否都在项['abc'].keys()中?