本記事の目的
内包表記の if 文で,条件に当てはまらない (else) の場合,何もしない処理 (pass)をしたい
例)
条件「偶数」の時,その数字をリストに格納し,
「偶数」でない場合 (else) ,何もしない (pass)
ans = [i if i % 2 == 0 else pass for i in range(10)]
# 下記のリストを作成したい
# [0, 2, 4, 6, 8]
実際にこれを実行すると以下のように怒られます.
File "<file_name>", line 7
ans = [i if i % 2 == 0 else pass for i in range(10)]
^
SyntaxError: invalid syntax
「無効な文法です」と怒られました...
結論
「if」を for の前ではなく後ろに記述する.
ans = [i for i in range(10) if i % 2 == 0]
# エラーが起きずに下記のリストが作成される
# [0, 2, 4, 6, 8]
これで目的が果たせました.
よかったです.
反論
とここで,ふと考えてみます.
else の場合は何もしないのであれば別に pass は記述しなくて良いのでは?
そもそも else は要らないのでは?
と思いましたので実行してみます.
# はじめにやろうとしてたこと (a)
ans = [i if i % 2 == 0 else pass for i in range(10)]
# else と pass を無くす (b)
ans = [i if i % 2 == 0 for i in range(10)]
では,(b) だけ実行してみます.
File "<file_name>", line 9
ans = [i if i % 2 == 0 for i in range(10)]
^
SyntaxError: expected 'else' after 'if' expression
「いや,if の後には else くるでしょ」と怒られました...
解説
ということで,下記を解説します.
# これは if の後に else を書かないと怒られる (A)
ans = [i if i % 2 == 0 for i in range(10)]
# これは if の後に else を書かなくても怒られない (B)
ans = [i for i in range(10) if i % 2 == 0]
まず,(A) と (B) の if は何だったのかですが,
- (A) : 三項演算子の if
- (B) : 通常の if 文
(A) の三項演算子の場合,「三項」というくらいなので,
下記のように a, b, c の三つの項を扱います.
なので,else が無いといわれ怒られます.
a if b else c
(B) の通常の if 文はご存知の if 文ですので,
else が無くても問題ないということになります.
[補足] 三項演算子
散々「三項演算子」と書きましたが,
正しくは条件式といいます.
条件式 (しばしば "三項演算子" と呼ばれます) は最も優先度が低いPython の演算です。
https://docs.python.org/ja/3/reference/expressions.html#conditional-expressions
下記のように記述します.
Trueの時 if 条件 else Falseの時
下記が例です.
変数「B」が,
True の時変数「A」に「真」,
Falseの時変数「A」に「偽」を格納したいとします.
これを三項演算子で書くとこのようになります.
# 通常の if
if B:
A = '真'
else:
A = '偽'
# 三項演算子で書くと
A = '真' if B else '偽'
このように,条件分岐を一行で書けるのがメリットですが,
本記事のように内包表記で else が不要な時に困るのがデメリットです.
(ついうっかり忘れて解決に時間がかかります...)
まとめ
内包表記の if 文で else の場合何もしない処理を入れたい時は,if 文を for 文の後ろに書く.
# for 文の後ろに if 文を書くと else 書かなくて良い
ans = [i for i in range(10) if i % 2 == 0]