Один вариант, хотя он требует установки пакета, будет itertation_utilities.replicate
:
>>> from iteration_utilities import replicate
>>> list(replicate(range(1, 5), 4))
[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4]
Если вы не хотите устанавливать этот пакет, функция replicate
по существу эквивалентно этой функции:
from itertools import repeat
def replicate(items, repeats):
for item in items:
for _ in repeat(None, repeats):
yield item
На всякий случай, если вы заинтересованы в производительности, я сделал несколько микропроцессоров для нескольких (не всех) предложенных альтернатив:
Как вы можете видеть, подходы NumPy и iteration_utilities
были самыми быстрыми, тогда как все остальные подходы были примерно одинаково быстрыми.
Интересно отметитьчто из этих других подходов подход list.extend
был самым быстрым и (мой) пользовательский генератор самым медленным.Я этого не ожидал.
А вот код для репликации эталонного теста:
from iteration_utilities import replicate
from itertools import chain, repeat
import numpy as np
def replicate_generator_impl(upper):
for item in range(1, upper):
for _ in repeat(None, 4):
yield item
def replicate_generator(upper):
return list(replicate_generator_impl(upper))
def iteration_utilities_replicate(upper):
return list(replicate(range(1, upper), 4))
def double_comprehension(upper):
return [i for i in range(1, upper) for _ in range(4)]
def itertools_chain(upper):
return list(chain(*([x] * 4 for x in range(1, upper))))
def itertools_chain_from_iterable(upper):
return list(chain.from_iterable(repeat(i, 4) for i in range(1, upper)))
def extend(upper):
a = []
for i in range(1, upper):
a.extend([i] * 4)
return a
def numpy_repeat(upper):
return np.repeat(np.arange(1, upper), 4)
from simple_benchmark import benchmark
funcs = [replicate_generator, iteration_utilities_replicate, double_comprehension, itertools_chain, itertools_chain_from_iterable, extend, numpy_repeat]
arguments = {2**i: 2**i for i in range(1, 15)}
b = benchmark(funcs, arguments, argument_name='size')
b.plot()
На случай, если вам интересно, как это будет выглядеть без подхода NumPy:
Отказ от ответственности: я являюсь автором iteration_utilities
и simple_benchmark
.