Pythonにはitertoolsというモジュールがあります。その名の通り、イテレータのユーティリティで、知ってるとちょっと便利な時があります。
そこで適当に使えそうなものを個人的なコード例とともにメモしておきます。Pythonは2.7です。
大体内包表記で等価な書き方ができるので、コードが簡潔になりそうなものだけまとめてみました。
(もっと簡潔に書けるものもあるかもしれません。もしあったらこっそり教えて下さい。)
複数のイテレータをまとめる
(実は今回chainを使ってみてちょっと便利だったのでこのメモを作りました)
from itertools import chain
# 例: a, bの各要素のfugaプロパティの和を取りたい
# itertools不使用
hoge = sum(x.fuga for y in (a, b) for x in y)
# 使用
hoge = sum(x.fuga for x in chain(a, b))
ありうる組み合わせを網羅
from itertools import combinations
# 例: 配列aの中の異なる2要素をほげほげしたい
# 同様に、異なるn要素をほげほげしたい時にも使える。
# 不使用
for i in xrange(len(a)):
for j in xrange(i + 1, len(a)):
hoge(a[i], a[j])
# 使用(i < jは保証されている)
for i, j in combinations(xrange(len(a)), 2):
hoge(a[i], a[j])
# あるいは
for a1, a2 in combinations(a, 2):
hoge(a1, a2)
itertoolsを使うのがよいかネストさせるのがよいかは迷うところです。
個人的にはネストが3重以上になりそうなら確実にitertoolsを使うと思います。
別の種類の添字を組み合わせたいならproduct
が使えます。例えばhoge(a[i], b[j])
したければ
for i, j in product(xrange(len(a)), xrange(len(b))):
hoge(a[i], b[j])
# もしくは
for ea, eb in product(a, b):
hoge(ea, eb)
とします。
hoge(i, j)
とhoge(j, i)
を区別するならpermutations
で。
hoge(i, i)
もカウントするならproduct(xrange(len(a)), repeat=2)
もしくはproduct(a, repeat=2)
でよいみたいです。
個人的にこういう複数のリストを舐めるコードを書かなきゃいけない時が多いので役に立ちそうです。
同じクラスをひとまとめ
from itertools import groupby
# 例: 同じ値を持つdict aのキーを表示
# 不使用
tmp = {}
for k, v in a.items():
if v in tmp:
tmp[v].append(k)
else:
tmp[v] = [k]
for k, v in tmp.items():
print "[%s] has value %s" % (' ,'.join(v), k)
# 使用
f = lambda k:a[k]
keys = sorted(a.keys(), key=f)
for k, v in groupby(keys, f):
print "[%s] has value %s" % (' ,'.join(v), k)
一旦sortしないといけません。
あとlist(groupby(hoge))
は無理です。
その他
あるイテレータを無限に繰り返し
repeat
です。zip
とかと組み合わせるとうれしいかも。