我有一个小的(detected_chems 。

还有一个更大的 (>1000) 可迭代的;包含 化学名称作为键 的字典 chem_db 化学特性字典作为值 。像这样:

{'chemicalx':{'property1':'smells','property2':'poisonous'},
 'chemicaly':{'property1':'stinks','property2':'toxic'}}

我正在尝试将所有检测到的化学物质与数据库中的化学物质进行匹配并提取它们的属性。

我已经研究了这些问题/答案,但似乎无法将其应用于我的案例(抱歉)
  • Is it possible to use 'else' in a list comprehension?
  • if/else in a list comprehension?
  • if/else in a list comprehension?
  • Python Nested List Comprehension with If Else

  • 所以我正在制作一个结果列表 res ,但我创建了这个列表,而不是使用 if x in 条件嵌套 for 循环。
    res = [{chem:chem_db[chem]}
           for det_chem in detected_chems
           for chem in chem_db.keys()
           if det_chem in chem]
    

    这在一定程度上有效!

    我(认为)在这里做的是创建一个字典列表,如果找到检测到的化学物质,它将具有化学名称(键)的键:值对和有关化学物质的信息(作为字典本身,作为值)在化学数据库 (chem_db) 中的某处。

    问题是并非所有检测到的化学物质都在数据库中找到。这可能是因为拼写错误或名称变化(例如它们包含数字)或类似的东西。

    所以为了解决这个问题,我需要确定哪些检测到的化学物质不匹配。我认为这可能是一个解决方案:
    not_matched=[]
    res = [{chem:chem_db[chem]}
           for det_chem in detected_chems
           for chem in chem_db.keys()
           if det_chem in chem else not_matched.append(det_chem)]
    

    由于 else not_matched.append(det_chem) 部分,我收到语法错误。

    我有两个问题:

    1)我应该在哪里放置else条件以避免语法错误?

    2) not_matched 列表可以在列表理解中构建吗,所以我不先创建那个空列表。
    res = [{chem:chem_db[chem]}
           for det_chem in detected_chems
           for chem in chem_db.keys()
           if det_chem in chem else print(det_chem)]
    

    我想要实现的是:
    in: len(detected_chems)
    out: 20
    in: len(res)
    out: 18
    in: len(not_matched)
    out: 2
    
    in: print(not_matched)
    out: ['chemical_strange_character$$','chemical___WeirdSPELLING']
    

    这将帮助我找到解决匹配问题的方法。

    最佳答案

    你应该

    if det_chem in chem or not_matched.append(det_chem)
    

    但话虽如此,如果你按照评论清理一下,我认为有一种更有效的方式来做你想做的事。上面的解释是 append 返回 None 所以整个 if 条件将评估为 False (但项目仍然附加到 not_matched 列表)

    回复:效率:
    res = [{det_chem:chem_db[det_chem]}
           for det_chem in detected_chems
           if det_chem in chem_db or not_matched.append(det_chem)]
    

    这应该快得多 - 字典键上的 for 循环是一个 O(n) 操作,而字典的使用正是因为查找是 O(1) 所以我们使用 det_chem in chem_db 查找而不是检索键并一一比较它们基于散列

    奖励:字典理解(解决问题 2)

    我不确定为什么要构建一个单键字典列表,但可能需要的是一个字典理解,如下所示:
    chem_db = {1: 2, 4: 5}
    detected_chems = [1, 3]
    not_matched = []
    res = {det_chem: chem_db[det_chem] for det_chem in detected_chems if
           det_chem in chem_db or not_matched.append(det_chem)}
    # output
    print(res) # {1: 2}
    print(not_matched) # [3]
    

    我无法想到在构建 not_matched 列表的同时还使用单个列表/字典理解构建 res

    关于带有 if else 条件的 Python 列表理解,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57786671/

    10-11 22:58
    查看更多