Help us understand the problem. What is going on with this article?

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

More than 3 years have 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 さんにご指摘頂きました。
それを基に加筆修正してあります。
いつもコメントありがとうございます。

kokorinosoba
はたらきたくない
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away