snippet: view plain - save this
1 class chunks(object):
2 """Lump items from iterable into chunks of specified size.
3
4 Instanciate the iterator passing a sequence of chunk sizes in
5 argument 1 and an iterable to consume in argument 2::
6
7 >>> for c in chunks([1,1,1], xrange(3)): print c
8 [0]
9 [1]
10 [2]
11
12 The list of chunk sizes may be any kind of sequence, for instance
13 a tuple or even a (possibly infinite) iterable::
14
15 >>> list(chunks((1,2,3), range(6)))
16 [[0], [1, 2], [3, 4, 5]]
17
18 The total size of the chunks may be less than the size of the
19 iterator: remaining items in the iterator are not consumed::
20
21 >>> for c in chunks([1,2], range(6)): print c
22 [0]
23 [1, 2]
24
25 As a special case, if a chunk has size 0, then an empty list is
26 returned in its place and no item from iterable is consumed::
27
28 >>> for c in chunks([2,0,2], range(4)): print c
29 [0, 1]
30 []
31 [2, 3]
32
33 """
34 def __init__(self, sizes, iterable):
35 """Constructor, taking sequence of chunk sizes and iterable to
36 consume."""
37 self.current_chunk = -1
38 self.sizes = sizes
39 self.iterable = iter(iterable)
40 def __iter__(self):
41 return self
42 def next(self):
43 """Return next chunk."""
44 self.current_chunk += 1
45 if self.current_chunk >= len(self.sizes):
46 raise StopIteration
47 return [ self.iterable.next()
48 for x in xrange(self.sizes[self.current_chunk]) ]

0 comments