有没有办法在Python中短路all()语句?
这样的事情:
return all([x != 0, 10 / x == 2, True, False, 7])
如果x为0,不会返回错误?
答案 0 :(得分:6)
这不起作用,因为在调用all
之前评估列表(即其所有项目)。在这种特殊情况下,你最好的选择是这样的:
return x != 0 and 10 / x == 2 and True and False and 7
我假设您已经知道这一点,所以如果列表项没有硬编码,我会为您提供另一个更通用的解决方案:
return all(f() for f in [lambda: x != 0, lambda: 10 / x == 2,
lambda: True, lambda: False, lambda: 7])
这样表达式只会在短路all
内进行评估。
答案 1 :(得分:6)
如果您的代码在发生器中,那么您也可以通过这种方式短路:
def test(x):
yield x != 0
yield 10/x == 2
yield True
yield False
yield 7
all(test(9))
答案 2 :(得分:3)
这不会像你想象的那样完全起作用,因为Python在将结果值传递给函数之前会计算其所有函数参数。换句话说,它会在调用10 / x == 2
之前将all
评估为单个值。 (与Mathematica形成对比,Mathematica将通过未评估的条件10 / x == 2
并完全符合您的要求。)
最简单的事情是,只要你知道将把这个列表传递给all
,就是使用Python的and
运算符的短路功能:
return all([x != 0 and 10 / x == 2, True, False, 7])
或者,您可以重写数学条件,使其不会除以零,
return all([x != 0, 10 == 2 * x, True, False, 7])
(注意浮点除法问题)。
如果你真的想模仿Mathematica传递未评估条件的行为,那么我能想到的唯一方法就是传递一个可调用的对象,当你调用它时会评估条件。例如,您可以将所有列表元素转换为lambda函数:
return all(f() for f in [lambda: x != 0, lambda: 10 / x == 2,
lambda: True, lambda: False, lambda: 7])
如果您不想将所有内容转换为函数,我想您可以想出一些只会调用实际可调用内容的包装器:
return all(f() if callable(f) else f in [x != 0, lambda: 10 / x == 2,
True, False, 7])
但老实说,这似乎是一团糟(除非您在Python中编写CAS :-P)。
答案 3 :(得分:1)
是肯定的。如果你希望它对于x == 0:
是假的all([x != 0, x!=0 and 10 / x == 2, True, False, 7])
只需确保任何值x都允许每个值。