Quite often, I found the need to process a list in pairs. I was wondering what would be a pythonic and effective way to do this, and found this on Google:
pairs = zip(t[::2], t[1::2])
I thought it was pythonic enough, but after a recent discussion of idioms against efficiency, I decided to do some tests:
import time from itertools import islice, izip def pairs_1(t): return zip(t[::2], t[1::2]) def pairs_2(t): return izip(t[::2], t[1::2]) def pairs_3(t): return izip(islice(t,None,None,2), islice(t,1,None,2)) A = range(10000) B = xrange(len(A)) def pairs_4(t):
These were the results on my computer:
1.48668909073 2.63187503815 1.14518594742 0.105381965637 1.35109519958 1.24571323395 0.00257992744446 1.46182489395 1.45924496651 0.00251388549805 1.70076990128 1.69825601578
If I interpret them correctly, this should mean that implementing lists, indexing lists, and splitting lists in Python is very effective. This result is both comforting and unexpected.
Is there any other βbestβ way to move a list in pairs?
Please note that if the list has an odd number of elements, the latter will not be in any of the pairs.
What would be the right way to ensure that all elements are included?
I added these two sentences from the answers to the tests:
def pairwise(t): it = iter(t) return izip(it, it) def chunkwise(t, size=2): it = iter(t) return izip(*[it]*size)
Here are the results:
0.00159502029419 1.25745987892 1.25586485863 0.00222492218018 1.23795199394 1.23572707176
Results so far
Most pythonic and very effective:
pairs = izip(t[::2], t[1::2])
Most effective and very pythonic:
pairs = izip(*[iter(t)]*2)
It took me a while to figure out that the first answer uses two iterators, and the second uses one.
To deal with sequences with an odd number of elements, it was proposed to increase the original sequence by adding one element ( None ), which connects to the previous last element, which can be achieved using itertools.izip_longest() .
Finally
Note that in Python 3.x, zip() behaves like itertools.izip() , and itertools.izip() missing.