compose関数

1から15まで続けて書くと123456789101112131415となる。これを1つの整数と考えると、この数は21けたで,1が8回使われている。

このとき、各数字の出現個数を求めてみる。

>>> def compose(fun1, fun2):
...     return lambda x, f1=fun1, f2=fun2: f1(f2(x))
...
>>> s = ''.join([`i` for i in range(1, 16)])
>>> s
'123456789101112131415'
>>> _ = range(10)
>>> # mapを2回使う
>>> zip(_, map(s.count, map(str, _)))
[(0, 1), (1, 8), (2, 2), (3, 2), (4, 2), (5, 2), (6, 1), (7, 1), (8, 1), (9, 1)]
>>> # もしくはcomposeによりmapを1回のみ使う
>>> zip(_, map(compose(s.count, str), _))
[(0, 1), (1, 8), (2, 2), (3, 2), (4, 2), (5, 2), (6, 1), (7, 1), (8, 1), (9, 1)]

compose関数を使うとネストが1段階フラット化されることにより、括弧の個数が減るし見やすい。パフォーマンスはどちらが早いか微妙だが、ここでは気にしないことにする。


問題は、Pythonにデフォルトでcomposeみたいなモノがあるのかということだが、恐らくないだろう。
あと、Rubyみたいに範囲リテラルがあったら、range(1, 16)でなく、1..15と書けるのになあ。_ = range(10)で、わざわざ_に代入しなくても括弧の個数を減らせるのに…。残念。