Reputation: 113
I know you can use zip or map to iterate through them an element at a time, but how would I efficiently loop through two lists 3 elements at a time? For example:
a = [1, 2, 3, 4, 5, 6]
b = [7, 8, 9, 10, 11, 12]
zip/map would allow me to order them like
[1, 7, 2, 8, 3, 9, 4, 10, 5, 11, 6, 12]
but how would I handle a case where I want
[1, 2, 3, 7, 8, 9, 4, 5 6, 10, 11, 12]
Upvotes: 1
Views: 78
Reputation: 11183
You could define your zip method, for example:
def zip_slices(iterables, n = 2):
if n < 2: n = 1
min_len = min([len(iterable) for iterable in iterables])
i, size = 0, min_len
while i < size-n+1:
tmp = []
for iterable in iterables:
tmp += iterable[i:i+n]
yield tmp
i += n
And use it to get the desired result
a = [1, 2, 3, 4, 5, 6, 7]
b = [7, 8, 9, 10, 11, 12]
[child for parent in zip_slices((a, b), 3) for child in parent]
#=> [1, 2, 3, 7, 8, 9, 4, 5, 6, 10, 11, 12]
The above list comprehension is flattening the output from zip_slice
:
list(zip_slices((a, b), 3))
#=> [[1, 2, 3, 7, 8, 9], [4, 5, 6, 10, 11, 12]]
Upvotes: 0
Reputation: 21275
Here's a solution using the itertools
recipe grouper
:
from itertools import zip_longest
a = [1, 2, 3, 4, 5, 6]
b = [7, 8, 9, 10, 11, 12]
def grouper(n, iterable, fillvalue=None):
"grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return zip_longest(fillvalue=fillvalue, *args)
res = []
for x, y in zip(grouper(3, a), grouper(3, b)):
res.extend(x + y)
print(res)
Result:
[1, 2, 3, 7, 8, 9, 4, 5, 6, 10, 11, 12]
Upvotes: 3