Edited at

リスト内包表記とif文を組み合わせるとき

More than 1 year has passed since last update.


はじめに

二番煎じかもしれないけど、よくリスト内包表記でわからなくなるのでメモ。


リスト内包表記

Pythonではリストを作るとき、appendを呼び出さないためにfor文より実行速度が速い、リスト内包表記というものがあります。

その代わりコードの可読性を著しく損なうという副作用がありますが、ワンライナーで書きやすいので私はよく使います。


if ... のみを使うとき

次のコードは9までの偶数のみを返すリスト内包表記です。

even_list = [i for i in range(10) if i % 2 == 0]

普通にfor文で書くと以下のようになります。

even_list = []

for i in range(10):
if i % 2 == 0:
even_list.append(i)

elseを使わないときはifをリスト内包表記の後に持ってくるのがポイント。

even_listの中身は、以下のようになります。

[0, 2, 4, 6, 8]

このひとつの特徴としては、内包表記の最後に現れるif文によって、range(10)で10個あった数が選択され、要素数が減っています。


if ... else ... を使うとき

次のコードは偶数のときは数字、奇数のときは "odd" を返すリスト内包表記です。

even_list = [i if i % 2 == 0 else "odd" for i in range(10)]

for文を使った例

even_list = []

for i in range(10):
if i % 2 == 0:
even_list.append(i)
else:
even_list.append("odd")

elseを使いたいときは、if文をリスト内包表記の一番前に書く必要があります。

even_listの中身は、以下のようになります。

[0, 'odd', 2, 'odd', 4, 'odd', 6, 'odd', 8, 'odd']

こちらは、else文があることによって、if文の条件に合致しなかった場合でも値が返ってくるので、要素数は減っていません。


補足

これはPythonの三項演算子(Pythonでは正しくは条件式と呼ぶみたいです)とを使っていて、

"even" if True else "odd"

のときに "even" が返ってくるのと同じ。

それをリスト内包表記のforの中で使っているだけです。


まとめ

else の有無
位置
構文
要素数

if ... のみを使うとき
ifは後ろ

[ ... for ... in ... if ... ]
ifの条件に合致しないと要素が減る

if ... else ... を使うとき
ifは

[ ... if ... else ... for ... in ... ]
要素数は減らない


... if ... else ... を三項演算子と呼ばないことや要素数関係の話は@shiracamus さんにご指摘頂きました。

それを基に加筆修正してあります。

いつもコメントありがとうございます。