I have a Python script which takes as input a list of integers, which I need to work with four integers at a time. Unfortunately, I don't have control of the input, or I'd have it passed in as a list of four-element tuples. Currently, I'm iterating over it this way:
for i in xrange(0, len(ints), 4):
# dummy op for example code
foo += ints[i] * ints[i + 1] + ints[i + 2] * ints[i + 3]
It looks a lot like "C-think", though, which makes me suspect there's a more pythonic way of dealing with this situation. The list is discarded after iterating, so it needn't be preserved. Perhaps something like this would be better?
while ints:
foo += ints[0] * ints[1] + ints[2] * ints[3]
ints[0:4] = []
Still doesn't quite "feel" right, though. :-/
Related question: How do you split a list into evenly sized chunks in Python?
To avoid all conversions to a list
import itertools
and:Produces:
I checked
groupby
and it doesn't convert to list or uselen
so I (think) this will delay resolution of each value until it is actually used. Sadly none of the available answers (at this time) seemed to offer this variation.Obviously if you need to handle each item in turn nest a for loop over g:
My specific interest in this was the need to consume a generator to submit changes in batches of up to 1000 to the gmail API:
I never want my chunks padded, so that requirement is essential. I find that the ability to work on any iterable is also requirement. Given that, I decided to extend on the accepted answer, https://stackoverflow.com/a/434411/1074659.
Performance takes a slight hit in this approach if padding is not wanted due to the need to compare and filter the padded values. However, for large chunk sizes, this utility is very performant.
Using little functions and things really doesn't appeal to me; I prefer to just use slices:
Another approach would be to use the two-argument form of
iter
:This can be adapted easily to use padding (this is similar to Markus Jarderot’s answer):
These can even be combined for optional padding:
It is easy to make
itertools.groupby
work for you to get an iterable of iterables, without creating any temporary lists:Don't get put off by the nested lambdas, outer lambda runs just once to put
count()
generator and the constant100
into the scope of the inner lambda.I use this to send chunks of rows to mysql.