簡體   English   中英

Python:any()檢查對象列表中的屬性是否與列表匹配

[英]Python: any() to check if attribute in List of Objects matches a list

我有一個從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'},
        {'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

解決方法

現在,我將對象屬性提取到一個新列表中,將兩個列表都轉換成集合並進行比較。

project_names = [project.project_name for project in projects]
assert set(project_list) <= set(project_names)

這是可行的,但對於復雜的對象和較長的列表將效率不高。

通過set方法很好,並且比任何嵌套循環方法都好。 您為什么認為效率低下?

次要優化是直接通過生成器表達式創建項目集,而不是提取臨時列表:

project_set = set(p.project_name for p in projects)

然后使用all而不是在project_list中進行設置:

assert all(p in project_set for p in project_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)

如果您確實需要短路行為:遍歷對象列表; 每次找到一個,您就關心將其添加到集合中; 一旦設置滿則返回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]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM