Ответ 1
import itertools
itertools.chain.from_iterable(itertools.repeat([1, 2, 3], 5))
Itertools - замечательная библиотека.:)
Я хотел бы циклически перебирать список (N раз) через итератор, чтобы фактически не хранить N копий списка в памяти. Есть ли встроенный или элегантный способ сделать это без написания моего собственного генератора?
В идеале, itertools.cycle(my_list) будет иметь второй аргумент, чтобы ограничить, сколько раз он циклы... увы, нет такой удачи.
import itertools
itertools.chain.from_iterable(itertools.repeat([1, 2, 3], 5))
Itertools - замечательная библиотека.:)
itertools.chain.from_iterable(iter(L) for x in range(N))
Для частного случая, когда вам нужно несколько раз перебирать список, это не так уж плохо.
Он создает список n
ссылок на my_list
, поэтому, если n
очень велико, лучше использовать ответ Дартфелта
>>> import itertools as it
>>> it.chain(*[my_list]*n)
Все остальные ответы превосходны. Другим решением было бы использовать islice
. Это позволяет прерывать цикл в любой момент:
>>> from itertools import islice, cycle
>>> l = [1, 2, 3]
>>> list(islice(cycle(l), len(l) * 3))
[1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> list(islice(cycle(l), 7))
[1, 2, 3, 1, 2, 3, 1]
Вы сказали, что не хотите писать свой собственный генератор, но выражение генератора, вероятно, будет самым простым и эффективным способом выполнить то, что вам нужно. Он не требует каких-либо вызовов функций или импорта каких-либо модулей. itertools
- отличный модуль, но, возможно, не нужен в этом случае?
some_list = [1, 2, 3]
cycles = 3
gen_expr = (elem for _ in xrange(cycles) for elem in some_list)
или просто
(elem for _ in xrange(3) for elem in [1, 2, 3])
или
for elem in (e for _ in xrange(3) for e in [1, 2, 3]):
print "hoo-ray, {}!".format(elem)
@Ответ Darthfett задокументирован как рецепты itertools:
from itertools import chain, repeat
def ncycles(iterable, n):
"Returns the sequence elements n times"
return chain.from_iterable(repeat(tuple(iterable), n))
list(ncycles(["a", "b"], 3))
# ['a', 'b', 'a', 'b', 'a', 'b']
Для удобства добавлю, что библиотека more_itertools
реализует этот рецепт (и многие другие) для вас:
import more_itertools as mit
list(mit.ncycles(["a", "b"], 3))
# ['a', 'b', 'a', 'b', 'a', 'b']