Thursday, April 4, 2019

Pairwise Iteration

The zip function in Python can be used in some really interesting ways.

One of those ways is for iterating through an iterable in consecutive pairs.

Consider this iterable:
l = [1, 2, 3, 4, 5, 6]
Suppose we need to iterate through this list pairwise as follows:
(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)
We could certain set up a loop of indices and do it the "normal" way, but a much more Pythonic way of doing this would be to use sequence slicing and the zip function as follows:
for t in zip(l, l[1:]):
    print(t)
which will give us the result:
(1, 2)(2, 3)(3, 4)(4, 5)(5, 6)
We can tweak this further to allow us to iterate thus:
(1, 2), (3, 4), (5, 6)

by writing it this way:
for t in zip(l[::2], l[1::2]):
    print(t)
which gives us the desired result:
(1, 2)(3, 4)(5, 6)
Of course we can expand on this to iterate in 3-tuple, 4-tuple, etc.

For example:
l = range(10)for t in zip(l, l[1::], l[2::]):
    print(t)
will result in this output:
(0, 1, 2)(1, 2, 3)(2, 3, 4)(3, 4, 5)(4, 5, 6)(5, 6, 7)(6, 7, 8)(7, 8, 9)
while this:
l = range(15)
for t in zip(l[::3], l[1::3], l[2::3]):
    print(t)
will result in this output:
(0, 1, 2)(3, 4, 5)(6, 7, 8)(9, 10, 11)(12, 13, 14)
For a three character function, zip packs a lot of punch!

2 comments:

  1. Wonderful idea. Recently I had a similar problem, that is to iterate through 1, 2, 3, ... as (1, 2), (3, 4), .. I would have preferred your idea had I read this post. I resorted to comprehensions though:
    iter_l = iter(l)
    pairs = [item, next(iter_l) for item in iter_l]
    Way less idiomatic. Thanks for the post!

    ReplyDelete
  2. I am back. I am looking for a generalized way of grouping items like: (1,2,3,4), (2,3,4,5), (3,4,5,6)...
    To attempt a challenge. Unfortunately its not here :(

    ReplyDelete

Looping N Times

The itertools  module is one of my favorite modules in the Python standard library! Here's an interesting example. Often we just wan...