我有一个方法,按顺序调用其他4个方法来检查特定的条件,并立即返回(不检查以下那些)每当一个返回一些真理。
def check_all_conditions():
x = check_size()
if x:
return x
x = check_color()
if x:
return x
x = check_tone()
if x:
return x
x = check_flavor()
if x:
return x
return None
这似乎是一大堆行李规定。而不是每个2行if语句,我宁愿这样做:
x and return x
但这是无效的Python。我是不是错过了一个简单、优雅的解决方案?顺便说一句,在这种情况下,这四个检查方法可能代价很高,所以我不想多次调用它们。
这是马丁第一个例子的一个变种。为了允许短路,它还使用了“可调用对象的集合”样式。
而不是循环,你可以使用内置的任何。
conditions = (check_size, check_color, check_tone, check_flavor)
return any(condition() for condition in conditions)
注意,any返回一个布尔值,所以如果您需要检查的确切返回值,这个解决方案将不起作用。any将不会区分14,'red', 'sharp', 'spicy'作为返回值,它们都将作为True返回。
对我来说,最好的答案是@ phill -frost,然后是@wayne-werner's。
我发现有趣的是,没有人说过一个函数将返回许多不同的数据类型,这将强制检查x本身的类型来做任何进一步的工作。
所以我会将@PhilFrost的回答与保持单一类型的想法混合在一起:
def all_conditions(x):
yield check_size(x)
yield check_color(x)
yield check_tone(x)
yield check_flavor(x)
def assessed_x(x,func=all_conditions):
for condition in func(x):
if condition:
return x
return None
注意,x被作为一个参数传递,但all_conditions也被用作检查函数的传递生成器,其中所有检查函数都得到一个要检查的x,并返回True或False。通过使用带有all_conditions作为默认值的func,您可以使用assessed_x(x),或者您可以通过func传递进一步的个性化生成器。
这样,只要一个检查通过,您就会得到x,但它总是相同的类型。
我很惊讶没有人提到内置的任何是为了这个目的:
def check_all_conditions():
return any([
check_size(),
check_color(),
check_tone(),
check_flavor()
])
注意,尽管这个实现可能是最清晰的,但它计算所有的检查,即使第一个检查为True。
如果你真的需要在第一次检查失败时停止,考虑使用reduce来将一个列表转换为一个简单的值:
def check_all_conditions():
checks = [check_size, check_color, check_tone, check_flavor]
return reduce(lambda a, f: a or f(), checks, False)
reduce(function, iterable[, initializer]):应用2的函数
参数从左到右累加到iterable的项,
从而将可迭代对象减少为单个值。左边的参数x,
累积值和正确的参数y是否更新
值。如果存在可选初始化式,则为
在计算中置于可迭代对象的项之前
在你的情况下:
lambda a, f: a或f()是检查累加器a或当前检查f()是否为True的函数。注意,如果a为True, f()将不会被求值。
检查包含检查函数(来自lambda的f项)
False是初始值,否则不会发生检查,结果总是True
Any和reduce是函数式编程的基本工具。我强烈建议你训练这些以及地图,这是很棒的!