Ber*_*ard 217 python if-statement
我有一个方法,按顺序调用其他4个方法来检查特定的条件,并在每次返回Truthy时立即返回(不检查以下的方法).
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
Run Code Online (Sandbox Code Playgroud)
这似乎是很多行李代码.而不是每个2行if语句,我宁愿做类似的事情:
x and return x
Run Code Online (Sandbox Code Playgroud)
但那是无效的Python.我在这里错过了一个简单优雅的解决方案吗?顺便说一下,在这种情况下,这四种检查方法可能很昂贵,所以我不想多次调用它们.
tim*_*geb 393
除了Martijn的好答案,你可以链接or.这将返回第一个真值,或者None如果没有真值:
def check_all_conditions():
return check_size() or check_color() or check_tone() or check_flavor() or None
Run Code Online (Sandbox Code Playgroud)
演示:
>>> x = [] or 0 or {} or -1 or None
>>> x
-1
>>> x = [] or 0 or {} or '' or None
>>> x is None
True
Run Code Online (Sandbox Code Playgroud)
Mar*_*ers 276
你可以使用一个循环:
conditions = (check_size, check_color, check_tone, check_flavor)
for condition in conditions:
result = condition()
if result:
return result
Run Code Online (Sandbox Code Playgroud)
这具有额外的优势,您现在可以使条件数变量.
你可以使用map()+ filter()(Python 3版本,使用Python 2中的future_builtins版本)来获得第一个这样的匹配值:
try:
# Python 2
from future_builtins import map, filter
except ImportError:
# Python 3
pass
conditions = (check_size, check_color, check_tone, check_flavor)
return next(filter(None, map(lambda f: f(), conditions)), None)
Run Code Online (Sandbox Code Playgroud)
但如果这更具可读性是值得商榷的.
另一种选择是使用生成器表达式:
conditions = (check_size, check_color, check_tone, check_flavor)
checks = (condition() for condition in conditions)
return next((check for check in checks if check), None)
Run Code Online (Sandbox Code Playgroud)
Jac*_*ley 86
不要改变它
正如各种其他答案所示,还有其他方法可以做到这一点.没有一个像你的原始代码一样清晰.
Way*_*ner 83
在与timgeb有效的答案中,您可以使用括号进行更好的格式化:
def check_all_the_things():
return (
one()
or two()
or five()
or three()
or None
)
Run Code Online (Sandbox Code Playgroud)
Phi*_*ost 74
根据Curly定律,通过分割两个问题,可以使这些代码更具可读性:
分为两个功能:
def all_conditions():
yield check_size()
yield check_color()
yield check_tone()
yield check_flavor()
def check_all_conditions():
for condition in all_conditions():
if condition:
return condition
return None
Run Code Online (Sandbox Code Playgroud)
这避免了:
...同时保留线性,易读的流程.
根据您的特定情况,您可能还可以提供更好的功能名称,这使其更具可读性.
小智 42
这是Martijns第一个例子的变种.它还使用"callables"风格,以便允许短路.
您可以使用内置而不是循环any.
conditions = (check_size, check_color, check_tone, check_flavor)
return any(condition() for condition in conditions)
Run Code Online (Sandbox Code Playgroud)
请注意,any返回一个布尔值,因此如果您需要检查的确切返回值,此解决方案将不起作用.any不会区分14,'red','sharp','spicy'作为返回值,将他们全部返回True.
zwo*_*wol 27
你考虑过只写if x: return x一行吗?
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
Run Code Online (Sandbox Code Playgroud)
这并不比你的重复少,但IMNSHO它读得更顺畅.
nga*_*ull 24
我很惊讶没有人提到any为此目的而制作的内置内容:
def check_all_conditions():
return any([
check_size(),
check_color(),
check_tone(),
check_flavor()
])
Run Code Online (Sandbox Code Playgroud)
请注意,尽管此实现可能是最清楚的,但它会评估所有检查,即使第一个检查是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)
Run Code Online (Sandbox Code Playgroud)
reduce(function, iterable[, initializer]):将两个参数的函数累加到可迭代的项目,从左到右,以便将迭代减少到单个值.左参数x是累加值,右参数y是迭代的更新值.如果存在可选的初始化程序,则将其放在计算中的iterable项之前
在你的情况下:
lambda a, f: a or f()是检查累加器a或当前检查的f()函数True.注意,如果a是True,f()将不会被评估.checks包含检查功能(f来自lambda 的项目)False 是初始值,否则不会发生检查,结果总是如此 Trueany并且reduce是函数式编程的基本工具.我强烈建议你训练这些以及map哪些也很棒!
Phi*_*net 19
如果你想要相同的代码结构,你可以使用三元语句!
def check_all_conditions():
x = check_size()
x = x if x else check_color()
x = x if x else check_tone()
x = x if x else check_flavor()
return x if x else None
Run Code Online (Sandbox Code Playgroud)
如果你看一下,我觉得这很好看.
演示:

对我来说,最好的答案是@ phil-frost,其次是@ wayne-werner。
我发现有趣的是,没有人说过一个函数将返回许多不同数据类型这一事实,这将使然后必须对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
Run Code Online (Sandbox Code Playgroud)
请注意,x它作为参数传递,但也all_conditions用作检查函数的传递生成器,其中所有函数都x将被检查,然后返回True或False。通过使用funcwith all_conditions作为默认值,您可以使用assessed_x(x),也可以通过传递进一步的个性化生成器func。
这样一来,您x就可以通过一张支票,但是它始终是同一类型。