Я не тупой эксперт, и "лучший" способ субъективен.Вот один из способов использования itertools
from itertools import chain, repeat
chain.from_iterable(repeat(elem, count) for elem, count in zip(my_array[::2], my_array[1::2]))
Вот подробное описание того, как это работает.
my_array[::2]
возвращает фрагмент, который является любым другим элементом, поскольку первый и второй аргументыоставлено пустым, начинается с 0 и продолжается до конца.Так что это будет весь ваш первый столбец, который является вашими элементами ввода.Ваши значения находятся в другом столбце, поэтому мы можем использовать my_array[1::2]
для получения значений.Эти фрагменты хороши тем, что они не создают новые копии вашего массива, а просто «представления», которые пропускают каждый второй элемент и начинаются с некоторого смещения.
Теперь мы хотим перечислить их попарно.Использование zip()
удобно для этого.Он использует итераторы / генераторы / последовательности параллельно и дает индивидуальную привязку для каждого элемента.Поэтому, когда мы проникаем в конструкцию for, мы привязываем каждый элемент к elem
, а каждый счет к count
.
Конструкция for in
позволяет нам обеспечить преобразование для каждой пары аргументов.Здесь мы используем repeat
для создания виртуальных повторений каждого элемента.Снова хорошо, что нам не нужно создавать новые массивы.Генератор repeat
просто сгенерирует входной элемент N раз.
Наконец, нам нужен способ объединить все эти повторяющиеся элементы в одно сведенное перечисление.Вот тут и приходит chain.from_iterable()
. Он потребляет многократные итерируемые элементы, развертываемые последовательно.Как и другие части, цепочка создаст новый генератор, а не новый список, поэтому мы снова сэкономим память.Если вы действительно хотите список, вы можете добавить его к list()
в конце.Или просто сделайте его входом для конструкции for in
.
Вот все, что разбито на отдельные операции с намерением-раскрывающими-переменными:
elements = my_array[::2]
counts = my_array[1::2]
bypairs = zip(elements, counts)
repeated = (repeat(elem, count) for elem, count in bypairs)
flattened = chain.from_iterable(repeated)
list(flattened)