I think the canonical, pythonic way to do this is to put a burden on the generator that you are repeating. I would define a generator function like this:
import itertools def generate_arrangements(iterable, size=4): iterator = iter(iterable) while True: yield next(iterator) yield list(list(row) for row in itertools.islice(iterator, size))
Say you have data in the list:
data = [ 5, [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16], 5, [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16] ]
Then record:
first_num, first_arr, second_num, second_arr = generate_arrangements(data)
gives the desired result:
>>> first_num 5 >>> first_arr [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
You can also specify the quantity and location at the same time, and ask the user to do additional unpacking, which can be more natural:
import itertools def generate_arrangements(iterable): iterator = iter(iterable) while True: number = next(iterator) arrangement = list(list(row) for row in itertools.islice(iterator, 4)) yield number, arrangement (first_num, first_arr), (second_num, second_arr) = generate_arrangements(data)
As @JoranBeasley writes in the comments, this form simplifies the use of unpacking tuples in a for loop, for example:
for num,arr in generate_arrangements(data): print(num) print(arr)