我开始学习Python了。我对这段代码中使用的单行代码(下面代码中的第 5 行)感到非常困惑。
有人可以向我解释一下这个衬垫是如何工作的吗?可以用冗长的方式重写吗?
multiset = [2, 2, 3, 3, 4, 5, 6, 7, 8, 10]
x = [0]
deltaSet = set(multiset)
for candidate in deltaSet:
if sum([(abs(candidate-member) in multiset) for member in x]) == len(x):
for member in x:
multiset.remove(abs(candidate-member))
x.append(candidate)
if len(x) == n: break
谢谢!
请您参考如下方法:
我相信您正在查看的行是:
sum([(abs(candidate-member) in multiset) for member in x])
首先,括号太多了。让我们摆脱我们不需要的东西:
sum(abs(candidate-member) in multiset for member in x)
呼,已经好多了。现在让我们逐个实际地看一下表达式:
abs(candidate - member) in multiset
这已经足够不言自明了……是候选的绝对值减去多重集中的成员吗?如果是,表达式返回 True,如果不是,表达式返回 False。现在成员是什么?好吧,可迭代的 x 中的每件事都有一个。所以你总结了一堆 True 和 False。在 python 中, bool 值是 int 的子类(True == 1 和 False == 0),总和基本上是计算我们之前讨论的表达式为 True 的次数。
然后他们检查它是否等于 len(x) 所以基本上,代码检查表达式是否 True for every x 中的成员。幸运的是,有一种更好的方法可以用 python 编写:
all(abs(candidate - member) in multiset for member in x)
如果这仍然令人困惑,我们可以将其重写为一个函数(我们称它为 f(x):
def f(x):
"""Equivalent to `all(abs(candidate - member) in multiset for member in x."""
for member in x:
if not abs(candidate - member) in multiset:
return False
return True
对于一些引用阅读,在这两种情况下,我都使用了生成器表达式(在语法和含义上类似于 list-comprehensions,但它们会即时生成“产生”的项目,而不是一次具体化整个列表. 对于某些操作,它们的内存效率更高且速度更快。它们在您不需要查看每个项目以了解结果的情况下特别有用(例如,单个 False足以使整个表达式 False)。
