Python リスト内包表現

Python で ASCII文字列のコードの和の下位8bit を作る、というプログラムがありました。

sum = 0
for chr in "hogehogehoge":
    sum += ord(chr)
sum = sum & 0xFF

つまりチェックサムです。
for 文を回しながら作ってあって、そこに「もうちょっといい方法はないか?」というコメントが書いてあれば、いろいろ考えてしまうのが人情です。

真っ先に浮かんだのが #inject:into: で、Smalltalk であればこんな感じになるはずです。

ret _ ('hogehogehoge' inject: 0 into:
          [ :sum :chr | sum + chr asciiValue ] ) bitAnd: 16rFF.

でも Python はコレクションクロージャメソッド に不自由なので、こういう場合はしょうがない、リスト内包表現をつかうと良いのかな。で、書いてみました*1

ret = sum( [ord(chr) for chr in "hogehogehoge"] ) & 0xFF

うがっ、脳内では #inject:into: の方がシンプルだったのに出来たコードの見た目は Python の方が綺麗ですねぇ。Smalltalk の優位性をほくそ笑むつもりだっただけに結構ショック。


* * *


#Collect: と #Select: があればたいていの事が出来てしまうわけで、コレクションクラスが異様に充実している Smalltalk とリストとタプルとディクショナリで全てをまかなう Python の対比的に、厳選したコレクションクロージャメソッド(相当)というのは美しい。

と、いうわけで 今更ながら リスト内包表現がマイブーム。なんでもかんでも リスト内包で書いてしまっていたりします(ゴールデンハンマー アンチパターン状態 (^^; )。それに、

 [ item for item in aCollection if item.attr == 'foo' ]

って、カギ括弧といい、後置修飾的な妙な語順といい、なにか琴線にふれるものがあるとおもいません?

*1:Python 2.4 からはジェネレータ表現が使えるので、このコードからリストのカギ括弧を省いてしまってもそのまま動きます。――ということをこの日記を書いている最中に知りました。