知に至る病

お勉強したことを忘れないように書き留めています。

Python の内包表記で if ~ else を使った場合分けをする

内包表記の中で場合分けしたい

Python の内包表記には if 節をつけることができます。

>>> [x for x in range(10) if x % 2 == 0]
[0, 2, 4, 6, 8]

しかし,これでできるのはデータのフィルタリングであって,else 節をつけて条件に応じて値を変えるということはできません。 条件に合致しないデータはすべて破棄されてしまいます。 試しに if 節の後に else 節をくっつけてみると Syntax Error になります。

>>> [x for x in range(10) if x % 2 == 0 else -x]
  File "<stdin>", line 1
    [x for x in range(10) if x % 2 == 0 else -x]
                                           ^
SyntaxError: invalid syntax

素直に if 文を使った形に書き下せばよいのですけれど,内包表記のまま条件分岐できないものかなと思って調べたら,ちゃんと解決方法がありました。

条件演算式を利用すればできる

条件演算式(三項演算子)を使えば内包表記で else 節を使うことができるようです。 条件演算式はその名前の通りなので,for 節の後ろではなく前に,iterable から取り出した要素を評価する式のところに書きます。 先ほどとは if の位置が変わっていることに注意してください。

>>> [x if x % 2 == 0 else -x for x in range(10)]
[0, -1, 2, -3, 4, -5, 6, -7, 8, -9]

FizzBuzz ワンライナー

条件演算式は入れ子にできるので,FizzBuzzワンライナーで書けてしまいます。

>>> ["fizzbuzz" if x % 15 == 0 else "fizz" if x % 3 == 0 else "buzz" if x % 5 == 0 else x for x in range(1, 16)]
[1, 2, 'fizz', 4, 'buzz', 'fizz', 7, 8, 'fizz', 'buzz', 11, 'fizz', 13, 14, 'fizzbuzz']

参考資料