3 回答
TA贡献1804条经验 获得超8个赞
你应该
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)]
这应该会更快det_chem in chem_db- 字典键上的 for 循环是一个 O(n) 操作,而使用字典正是因为查找是 O(1) 所以我们使用哈希查找而不是检索键并一一比较它们基于
奖励:dict理解(解决问题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使用单个列表/字典理解进行构建。
TA贡献1836条经验 获得超13个赞
您的语法错误来自于理解不接受else子句的事实。
您最终可以使用... if ... else ...三元运算符来确定要放入您的理解结果的值。如下所示:
not_matched=[]
res = [{chem:chem_db[chem]} if det_chem in chem else not_matched.append(det_chem)
for det_chem in detected_chems
for chem in chem_db.keys()]
但这将是一个坏主意,因为您将None在您的resfor each notmatched中。这是因为... if ... else ...运算符始终返回一个值,在您的情况下,该值将是list.append方法的返回值(= None)。然后,您可以过滤res列表以删除None值,但是......嗯......
更好的解决方案是简单地保持您的第一理解并获得原始chem列表和列表之间的差异res:
not_matched = set(chems).difference(<the already matched chems>)
请注意,我使用了已经匹配的 chems占位符而不是真正的代码块,因为您的存储方式res根本不实用。事实上,它是一个单键字典列表,这是不合理的。字典的作用是保存由键标识的多个值。
对此的解决方案是res使用字典理解来制作字典而不是列表:
res = {chem: chem_db[chem]
for det_chem in detected_chems
for chem in chem_db.keys()
if det_chem in chem}
这样做,已经匹配的化学占位符可以替换为res.values()
另外,即使在很多情况下推导是一个非常酷的功能,它们也不是一个应该在任何地方都使用的神奇功能。嵌套理解真的很难读,应该避免(至少在我看来)。
TA贡献2003条经验 获得超2个赞
列表理解形式上最多包含 3 个部分。让我们在一个例子中展示它们:
[2 * i for i in range(10) if i % 3 == 0]
第一部分是一个表达式——它可能是(或在其中使用)三元运算符(
x if y else z
)第二部分是一个列表(或嵌套
for
循环中的更多列表),用于从中选择变量的值。第三部分(可选)是一个过滤器(用于在第2 部分中进行选择) -这里不允许使用子句!
else
所以如果你想使用else
分支,你必须把它放到第一部分,例如
[2 * i if i < 5 else 3 * i for i in range(10) if i % 3 == 0]
添加回答
举报