Python基于键值是否包含另一个lis中的所有项的字典筛选列表

2024-03-28 15:22:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个类似这样的字典列表,但是大约有500个条目:

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

sampleFilterList = ['123', '456']

我试图过滤列表中的所有结果,其中sampleFilterList中的所有值都在键“abc”中

结果应该是一个列表:

^{pr2}$

我试过[i for i in listOfDicts if a for a in sampleFilterList in i['abc']],但是我得到了UnboundLocalError: local variable 'a' referenced before assignment


Tags: inid列表forif字典foolocal
3条回答

这是一个包含嵌套列表理解的工作版本。您的问题是a for a in...是一个列表理解,需要在构造新列表时使用。在

[i for i in listOfDicts if [a for a in sampleFilterList if a in i['abc']] == sampleFilterList]

您需要将条件测试中的移到列表理解中的for关键字之前,并且使用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

^{pr2}$

首先,将第二个列表转换为一组,以便进行更有效的比较:

sampleFilterSet = set(sampleFilterList)

现在,将每个列表项的“abc”键与上述集合进行比较:

^{pr2}$

这是最快的解决方案。一种更具python风格(但速度稍慢)的解决方案是使用filter()

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

相关问题 更多 >