あ...ありのままに今起こったことを話すぜ!
※今回は特別編です
目次
そもそもことのはじまりは
金曜日のミノ駆動本_読書会(7章 コレクション)に向けて予習1をしていたnikkie氏。
『Effective Python 第2版』を読んでいると...
内包表記は、複数のif条件もサポートします。
同一のループでの複数条件は、暗黙のand式となります。(項目28より)
複 数 の if 条 件 だ と ...
ifを複数使った内包表記、動くんです!
Effective Pythonのサンプルコードを参照しましょう。
https://github.com/bslatkin/effectivepython/blob/4ae6f3141291ea137eb29a245bf889dbc8091713/example_code/item_28.py#L79-L86
1〜10の整数の中から4より大きい偶数を取り出すコードです。
>>> # 内包表記にifを複数書ける!! >>> b = [x for x in range(1, 11) if x > 4 if x % 2 == 0] >>> b [6, 8, 10] >>> # 複数のifはandと同じ >>> c = [x for x in range(1, 11) if x > 4 and x % 2 == 0] >>> c [6, 8, 10] >>> b == c True
私、ずっとandを連ねて書いてました〜
言語リファレンスの構文定義を確認
6.2.4. リスト、集合、辞書の表示を確認しました。
BNFの構文定義を読んでみると
comp_for
の定義でcomp_iter
はオプショナルcomp_iter
はcomp_for
またはcomp_if
comp_if ::= "if" or_test [comp_iter]
- つまり、
comp_if
のあとにcomp_iter
であるcomp_if
を続けられる=複数ifを書ける or_test
は今回深く追っていませんが、ブール演算や比較など、True
/False
を返すものっぽいという理解です
- つまり、
また、PEG2の説明では
listcomp: | '[' named_expression for_if_clauses ']'
for_if_clauses
はfor_if_clause
の1つ以上の繰り返しfor_if_clause
は、雑に言うと、for ... in ... (if ...)*
(if ...)*
はifの0個以上の繰り返し、つまり複数のifが書ける!
※10. 完全な文法仕様のComprehensions & Generatorsを見ています
構文定義でも内包表記の複数ifは明示されていたのですね...
終わりに
Pythonを書き始めて5年ほどだと思いますが、内包表記に複数のifというのは初めて知りました。
過去の私はなにかの書籍やWeb上のリソースで内包表記を身に着けたのだと思いますが、複数ifが書けることは見逃したのか書かれていなかったのか、今回初めて知って相当な衝撃を受けました。
if、お前、内包表記で複数使えたのか...
5 年 ぶ りに真実に近づいたぞ...
書ききってみて、if文がネストできることを考えるとようやく自然な気がしてきました