找出哪个条件打破了逻辑 and 表达式

Find out which condition breaks a logical and expression

我想找到一种优雅的方法来获取下面的逻辑 and 表达式的组件,如果 if 块是 而不是 已执行。

if test1(value) and test2(value) and test3(value):
   print 'Yeeaah'
else:
   print 'Oh, no!', 'Who is the first function that return false?'

如果输入了 else 块,我如何通过返回第一个虚假值来确定是 test1test2 还是 test3 负责?

齐发

我们可以将该测试值存储在列表中,然后检查它们是否都为 True,如果不为 False,则打印第一个值的索引。

def test1(x):
    return True
def test2(x):
    return False
def test3(x):
    return True

value = 'a'
statements = [test1(value), test2(value), test3(value)]

if all(statements):
   print('Yeeaah')
else:
   print('Oh, no! Function that first return False is {}'.format(statements.index(False)))

输出:

Oh, no! Function that first return False is 1

三路拆分:

使用 python3 语法:

b1 = test1(value)
b2 = test2(value)
b3 = test3(value)

if b1 and b2 and b3:
    print("Yeah")
else:
    print("Nope! 1: {}, 2: {}, 3: {}".format(b1, b2, b3))

您可以使用 next 和生成器表达式:

breaker = next((test.__name__ for test in (test1, test2, test3) if not test(value)), None)

演示:

>>> def test1(value): return True
>>> def test2(value): return False
>>> def test3(value): return True
>>> value = '_' # irrelevant for this demo
>>>
>>> tests = (test1, test2, test3)
>>> breaker = next((test.__name__ for test in tests if not test(value)), None)
>>> breaker
'test2'
>>> if not breaker:
...:    print('Yeeaah')
...:else:
...:    print('Oh no!')
...:    
Oh no!

请注意,此代码中从未调用 test3

(超级极端情况:如果出于我无法理解的原因恶作剧者将函数的 __name__ 属性重新分配给 '',请使用 if breaker is not None 而不是 if not breaker。)

~编辑~

如果您想知道第一个、第二个或第 n 个测试是否返回了 falsy,您可以使用与 enumerate 类似的生成器表达式。

>>> breaker = next((i for i, test in enumerate(tests, 1) if not test(value)), None)
>>> breaker
2

如果您想从零开始计数,请使用 enumerate(tests) 并检查 if breaker is not None 以进入 if 块(因为 0falsy 喜欢 None).