if文を最小限に抑える
前回書いたPythonに欲しい機能、Common Lispのcond
ですが、即席で考えて作ってみました。コードは以下のようになりました。インデントはうまく表示されておりませんが、スペース4つです。
def cond(value, conditions, guard):
exec(value)
for test, form in conditions:
if eval(test) is True:
return form
break
else:
return guard
そして使い方は以下のように、何となく見た目は似た感じに仕上がりました。
for i in range(16):
print(cond(f"x = {i}", [
("x % 15 == 0", "FizzBuzz"),
("x % 5 == 0", "Buzz"),
("x % 3 == 0", "Fizz")
],
i
))
とりあえずFizzBuzzはうまく結果を表示できました。exec
やらeval
あたりを使用しているので、このままでは安全性はゼロと言っても過言ではないでしょう。一応
cond
の各パラメータの説明をしますと、value
は変数宣言の文字列、conditions
は、testの文字列とformの文字列のタプルのリスト、guard
は最終的にどのtestにもパスしなかった場合に返す「もの」、という形になっており、やや制約があります。「もの」としましたのは、ここに関数も入れることが可能だからです。上記のコードに少し追加して、数字として表示される値をHelloに変えて表示するということも可能です。
def hello():
return "Hello"
for i in range(16):
print(cond(f"x = {i}", [
("x % 15 == 0", "FizzBuzz"),
("x % 5 == 0", "Buzz"),
("x % 3 == 0", "Fizz")
],
hello()
))
結果は以下のようになります。
$ python cond.py
FizzBuzz
Hello
Hello
Fizz
Hello
Buzz
Fizz
Hello
Hello
Fizz
Buzz
Hello
Fizz
Hello
Hello
FizzBuzz
しかしながら、もう少しいい感じに使い勝手がよいものを作成したいものです。