我有一个小的 (<100) 化学名称列表,名为 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/