15

What is the most efficient method to repeat a list up to a max element length?

To take this:

lst = ['one', 'two', 'three']
max_length = 7

And produce this:

final_list = ['one', 'two', 'three', 'one', 'two', 'three', 'one']

See also How to replicate array to specific length array for Numpy-specific methods.

See also Circular list iterator in Python for lazy iteration over such data.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Pylander
  • 1,531
  • 1
  • 17
  • 36
  • I un-duped this because slicing an `itertools.cycle` is only one way to solve the problem. Creating a definite list of data is different from being able to iterate over the data. – Karl Knechtel Oct 04 '22 at 02:29

2 Answers2

26

I'd probably use iterools.cycle and itertools.islice:

>>> from itertools import cycle, islice
>>> lst = [1, 2, 3]
>>> list(islice(cycle(lst), 7))
[1, 2, 3, 1, 2, 3, 1]
mgilson
  • 300,191
  • 65
  • 633
  • 696
11

Multiply appropriately?

>>> lst = ['one', 'two', 'three']
>>> max_length = 7
>>> 
>>> q, r = divmod(max_length, len(lst))
>>> q * lst + lst[:r]
['one', 'two', 'three', 'one', 'two', 'three', 'one']

Benchmarked mine and mgilson's solution, mine looks more efficient, for example for the below test mine takes about 0.7 seconds while mgilson's takes about 2.8 seconds.

from timeit import timeit
data = "lst = ['one', 'two', 'three'] * 1000; max_length = 12345678"

print(timeit('q, r = divmod(max_length, len(lst)); q * lst + lst[:r]',
             data,
             number=10))

print(timeit('list(islice(cycle(lst), max_length))',
             data + '; from itertools import cycle, islice',
             number=10))
Stefan Pochmann
  • 27,593
  • 8
  • 44
  • 107