N 個の組
L[0:2], L[1:3], L[2:4] …のような値を返すイテレータについてのメモ。ほぼ itertools ライブラリドキュメントのレシピ のまま。
L[0:2], L[1:3], L[2:4] … のようなイテレータ
レシピにそのものが載っていたので転載。
from itertools import * def pairwise(iterable): "s -> (s0,s1), (s1,s2), (s2, s3), ..." a, b = tee(iterable) next(b, None) return izip(a, b)
L[0:n], L[1:n+1], L[2:n+2] … のようなイテレータ
さきほどの pairwise と consume, repeatfunc というレシピらを参考に作成してみた。
今、疑問に思っている点は値の読み捨てに for 文、 for _ in xrange(n): next(it) ではなく collections.deque を使う理由について。こちらのほうが早いのだろうか? CPython の collections.deque は C 実装なので for 文より早い、とか? 後でベンチとってみようっと。
import itertools import collections def setwise(iterable, n=2): "s -> (s0,s1, ...), (s1,s2,...), (s2,s3,...), ..." its = itertools.tee(iterable, n) for i, it in enumerate(its): collections.deque( itertools.imap(next, itertools.repeat(it, i)), maxlen=0) return itertools.izip(*its)
使用例、連続する値を見つける
setwise を用いて整数値イテレータブルから、連続する値を見つけてみる。 itertools.ifilter 併用。
>>> from itertools import ifilter, izip, count, starmap >>> from operator import eq >>> def is_consecutive_numbers(nums): ... it = iter(nums) ... num = next(it) ... return all(starmap(eq, izip(it, count(num + 1)))) ... >>> data = [1, 4,5, 9,10,11, 16,17,18,19] >>> for n in ifilter(is_consecutive_numbers, setwise(data, 2)): ... print n ... (4, 5) (9, 10) (10, 11) (16, 17) (17, 18) (18, 19) >>> for n in ifilter(is_consecutive_numbers, setwise(data, 3)): ... print n ... (9, 10, 11) (16, 17, 18) (17, 18, 19)
別解、 itertools.groupby 併用。
>>> from itertools import groupby, imap >>> from operator import itemgetter >>> data = [1, 4,5, 9,10,11, 16,17,18,19] >>> for k, g in groupby(enumerate(data), lambda (i,x):i-x): ... for n in setwise(imap(itemgetter(1), g), 2): ... print n ... (4, 5) (9, 10) (10, 11) (16, 17) (17, 18) (18, 19) >>> for k, g in groupby(enumerate(data), lambda (i,x):i-x): ... for n in setwise(imap(itemgetter(1), g), 3): ... print n ... (9, 10, 11) (16, 17, 18) (17, 18, 19)
L[n*0:n*1], L[n*1:n*2], L[n*2:n*3] … のようなイテレータ
これも載っているので、ついでに転載。
from itertools import * def grouper(n, iterable, fillvalue=None): "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" args = [iter(iterable)] * n return izip_longest(fillvalue=fillvalue, *args)