Python:any()检查对象列表中的属性是否与列表匹配
我有一个从SQLAlchemy查询返回的对象列表Python:any()检查对象列表中的属性是否与列表匹配,python,data-structures,iterator,generator,Python,Data Structures,Iterator,Generator,我有一个从SQLAlchemy查询返回的对象列表 projects = [ {'project_id': 1, 'project_name': 'A'}, {'project_id': 2, 'project_name': 'B'}, {'project_id': 3, 'project_name': 'C'}, {'project_id': 4, 'project_name': 'D'}, {'projec
projects =
[
{'project_id': 1, 'project_name': 'A'},
{'project_id': 2, 'project_name': 'B'},
{'project_id': 3, 'project_name': 'C'},
{'project_id': 4, 'project_name': 'D'},
{'project_id': 5, 'project_name': 'E'},
{'project_id': 6, 'project_name': 'F'}
]
我要确保对象列表中包含此列表中的项目名称:
project_list = ['A', 'B', 'C']
如果它只是一个值,我可以使用
any(p.project_name == "A" for p in projects)
如何与列表进行类似的比较?比如:
any(p.project_name in project_list for p in projects)
上面的代码可以工作,但我怀疑any()
只要有一个匹配项,就会返回True
变通办法
现在,我正在将object属性提取到一个新列表中,将两个列表转换为集合并进行比较
project_names = [project.project_name for project in projects]
assert set(project_list) <= set(project_names)
project\u name=[project.project\u项目中项目的名称]
断言集(项目列表)您可以使用all
:
all(any(p_name==p.project_name for p in projects) for p_name in projects_list)
或更具可读性:
appears = lambda p_name: any(p_name==p.project_name for p in projects)
all(appears(p_name) for p_name in projects_list)
您可以使用all
:
all(any(p_name==p.project_name for p in projects) for p_name in projects_list)
或更具可读性:
appears = lambda p_name: any(p_name==p.project_name for p in projects)
all(appears(p_name) for p_name in projects_list)
您通过set
执行此操作的方法很好,并且比任何嵌套循环方法都要好。你为什么认为它效率低下
次要优化是通过生成器表达式直接创建项目集,而不是提取临时列表:
project_set = set(p.project_name for p in projects)
然后使用all
,而不是设置项目列表
:
assert all(p in project_set for p in project_list)
您通过set
执行此操作的方法很好,并且比任何嵌套循环方法都要好。你为什么认为它效率低下
次要优化是通过生成器表达式直接创建项目集,而不是提取临时列表:
project_set = set(p.project_name for p in projects)
然后使用all
,而不是设置项目列表
:
assert all(p in project_set for p in project_list)
如果您确实需要短路行为:遍历对象列表;每次你找到一个你关心的,把它加入一个集合;一旦该集合完全返回True
;否则返回False
def f(projects, project_list):
project_list = set(project_list)
seen = set()
for p in projects:
if p.project_name in project_list:
seen.update(p.project_name)
if seen == project_list:
return True
return False
抱歉,没有简洁的一行。如果您确实需要短路行为:遍历对象列表;每次你找到一个你关心的,把它加入一个集合;一旦该集合完全返回True
;否则返回False
def f(projects, project_list):
project_list = set(project_list)
seen = set()
for p in projects:
if p.project_name in project_list:
seen.update(p.project_name)
if seen == project_list:
return True
return False
对不起,没有简洁的一行。您可能会喜欢以下内容
'Project name' in [p.project_name for p in projects]
您可能会喜欢以下内容
'Project name' in [p.project_name for p in projects]
这是正确的方法。这是正确的方法。