Pablo Lucena writes: > 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
First line should be a1, b2, c3, d4, right? > The way I thought about doing this is as follows: > > from collections import deque > from itertools import cycle [...] > 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 =) Here's a combination of itertools (chaining of slices for the rotations) and builtin machinery (argument spreading, a generator expression, zip, enumerate) that seems to have the desired effect. from itertools import chain, islice l1 = ['a1', 'a2', 'a3', 'a4'] l2 = ['b1', 'b2', 'b3', 'b4'] l3 = ['c1', 'c2', 'c3', 'c4'] l4 = ['d1', 'd2', 'd3', 'd4'] n = 4 chainfrom = chain.from_iterable print(*chainfrom(zip(*(chain(islice(m, k, n), islice(m, 0, k)) for k, m in enumerate([l1, l2, l3, l4]))))) # prints: a1 b2 c3 d4 a2 b3 c4 d1 a3 b4 c1 d2 a4 b1 c2 d3 -- https://mail.python.org/mailman/listinfo/python-list