Cycling through iterables diagonally

marco.nawijn at colosso.nl marco.nawijn at colosso.nl
Fri Feb 26 09:27:50 EST 2016


On Friday, February 26, 2016 at 8:44:38 AM UTC+1, Pablo Lucena wrote:
> Hello,
> 
> I am trying to accomplish the following:
> 
> Say I have a group of 4 lists as follows:
> 
> l1 = ['a1', 'a2', 'a3', 'a4']
> l2 = ['b1', 'b2', 'b3', 'b4']
> l3 = ['c1', 'c2', 'c3', 'c4']
> l4 = ['d1', 'd2', 'd3', 'd4']
> 
> I would like to cycle through these lists "diagonally" in groups of
> len(list) (in this example, each list has 4 items).
> 
> cycle1: a1, b2, b3, b4
> cycle2: a2, b3, c4, d1
> cycle3: a3, b4, c1, d2
> cycle4: a4, b1, c2, d3
> 
> The way I thought about doing this is as follows:
> 
> from collections import deque
> from itertools import cycle
> 
> l1 = deque(['a1', 'a2', 'a3', 'a4'])
> l2 = deque(['b1', 'b2', 'b3', 'b4'])
> l3 = deque(['c1', 'c2', 'c3', 'c4'])
> l4 = deque(['d1', 'd2', 'd3', 'd4'])
> 
> l1.rotate(-0)
> l2.rotate(-1)
> l3.rotate(-2)
> l4.rotate(-3)
> 
> groups = cycle([l1, l2, l3, l4])
> 
> In [115]: for group in groups:
>    .....:     if not group:
>    .....:         break
>    .....:     print(group.popleft())
>    .....:
> a1
> b2
> c3
> d4
> a2
> b3
> c4
> d1
> a3
> b4
> c1
> d2
> a4
> b1
> c2
> d3
> 
> Prior to this I was mucking around with index counting while looping, and
> popping lists out of a deque, popping an item out of the list, and
> appending the list back into the deque during each iteration.
> 
> Is there a better/cleaner way to do this? I was hoping for some cool
> itertools logic =)
> 
> Thanks!
> 
> 
> -- 
> *Pablo*

Hello Pablo,

If you don't mind using third-party packages you 
could this quite straighforward with numpy:
(Python 2.7)

import numpy as np

a = np.array([
  ('a1', 'a2', 'a3', 'a4'),
  ('b1', 'b2', 'b3', 'b4'),
  ('c1', 'c2', 'c3', 'c4'),
  ('d1', 'd2', 'd3', 'd4')], dtype=str)

nrows, ncols = a.shape

for i in range(ncols):
    print np.diag(np.roll(a, -i, axis=1))

This prints:

['a1' 'b2' 'c3' 'd4']
['a2' 'b3' 'c4' 'd1']
['a3' 'b4' 'c1' 'd2']
['a4' 'b1' 'c2' 'd3']



More information about the Python-list mailing list