LoginSignup
21
21

More than 5 years have passed since last update.

Pythonのitertoolsは知ってるとちょっと便利

Last updated at Posted at 2015-12-17

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とかと組み合わせるとうれしいかも。

21
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
21