1. ホーム
  2. パイソン

[解決済み】「if x: return x」文を回避するためのPythonicな方法

2022-04-07 15:46:54

質問

あるメソッドがあり、特定の条件をチェックするために他の4つのメソッドを順番に呼び出し、1つが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

これはお荷物コードが多いような気がします。各2行のif文の代わりに、次のようなことをしたい。

x and return x

しかし、これは無効なPythonです。私はここでシンプルでエレガントな解決策を見逃しているのでしょうか?ちなみに、この状況では、これらの4つのチェックメソッドは高価になる可能性があるので、何度も呼び出したくはありません。

解決方法は?

ループを使えばいいんだよ。

conditions = (check_size, check_color, check_tone, check_flavor)
for condition in conditions:
    result = condition()
    if result:
        return result

これによって、条件の数を可変にできるようになったという利点もあります。

を使うことができます。 map() + filter() (Python3バージョンでは future_builtins バージョン をPython 2で使用した場合)、そのような最初にマッチする値を取得します。

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)

が、この方が読みやすいかどうかは議論の余地がある。

また、ジェネレータ式を使うという方法もある。

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)