找出哪个条件打破了逻辑 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
块,我如何通过返回第一个虚假值来确定是 test1
、test2
还是 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
块(因为 0
是 falsy 喜欢 None
).
我想找到一种优雅的方法来获取下面的逻辑 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
块,我如何通过返回第一个虚假值来确定是 test1
、test2
还是 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
块(因为 0
是 falsy 喜欢 None
).