Pythonで Scalaの findのように条件にマッチする最初の要素をリストから取得する

PHP Python Scala

lambdaは書いても ifや forは書きたくないあなたに

あるリストから、ある条件を満たす最初の要素を取り出したい。例えば、適当に並んだ語のリストから4文字以上の長さを持つ最初のものを取り出したい。きわめて簡潔な記述で。

この瞬間に「4文字以上の語がリストに含まれてない場合どうすんの」って返しがギャバンの蒸着よりも速く出てくるのが正しいプログラマです。「あっ、そんなことは考えもしなかった」っていう人はプログラマに向いてないし、ソフトウェアを設計する仕事にも向いてません(才能的な意味で向いていないというより適切な訓練が足りないというべきですが)。

もしリストに 4文字以上の語が含まれていない場合は Noneを返すことにしましょう。

とはいえ、正しいプログラマの傾向を日常生活に持ち込むと疎まれがちなので注意しましょう。→「ねえ、りんご3個買ってきて〜」「・・・」「どうしたの?」「2個しか売ってなかったらどうする?」「ファッ!?!?!?」

Scalaの場合

val list = List("foo", "hoge", "bar")
list.find(_.length >= 4)  // Some(hoge)

まるで空気でも吸うかのごとく簡潔にキマりました。ループも条件分岐も見当たりません。いわゆる関数型と呼ばれる言語では大体こんなふうになるんだと思います。

Pythonの場合

この記事の本題です。このコードスニペットを gistにメモしておく代わりにこの記事を書き起こしたようなものです。

Pythonでもループなんか使わず簡潔に書きたい。そうですよね。リストの要素に何かの順次処理をするためのイテレータを生成するユーティリティとして itertools なるモジュールがあるらしいのでそれを使ってみます。

list = ["foo", "hoge", "bar"]
next(itertools.ifilter(lambda x:len(x) >= 4, list), None)  # 'hoge'

Scalaのように簡潔とはいかないけど、こんな感じになります。ifilterは、あるリストの各要素を与えられた関数で評価し真となるものだけを順に返すイテレータを生成して返します。それに対して next を一度だけ適用することで条件を満たす最初の要素が得られます。nextの第二引数としてデフォルト値 Noneを与えているので、該当する要素が存在しない場合は例外が出る代わりに Noneが返ります。

参考: Python: find first element in a sequence that matches a predicate - Stack Overflow

おまけ: じゃ、じゃあPHPでも簡潔に!

_人人人人_
> 無理 <
 ̄Y^Y^Y ̄

$list = Array("foo", "hoge", "bar");
$result = null;  // PHPでは Noneじゃなくて null
foreach ($list as $item) {
    if (strlen($item) >= 4) {
        $result = $item;
        break;
    }
}

ループも条件分岐もローカル変数も必要です。

バグの数はおおよそプログラムの長さに比例すると考えると PHPはご愁傷様としかいいようがありません。それでも世の中には PHPしか(動かせないサーバ|運用出来ない体制|知らない人)が多いことから受託の案件ではどうしても使わざるを得ないあたりに Web開発の闇はとどまることなくひろがりんぐです。

補足

記事として記述の簡潔さを題材にしているのだから、確かにそちらのほうが良かったかもしれないです。

同じカテゴリの記事

feedgeneratorを使って PythonでRSSを出力する 2014年1月23日
ScalikeJDBCを Springで使う 2013年12月25日
JSON APIを Pythonから呼び出して結果を表示する 2013年10月25日
Amazonの Product Advertising APIを Scalaから呼び出す 2013年8月20日

お勧めカテゴリ

英語でアニメ観ようず
なじみ深い日本製アニメの英語版DVDで、字幕と音声から英語を学びましょうという趣旨のシリーズ記事です。
ScalaのようでJavaだけど少しScalaなJSON API
Scalaと Spring Frameworkを使って REST的なJSON APIを実装してみましょう。
ドクジリアン柔術少女 すから☆ぱいそん
代表 嶋田大貴のブログです。写真は神仏に見せ金をはたらく罰当たりの図