我想通過一個迭代器反覆遍歷一個列表(N次),以免在列表中實際存儲N個列表副本。有沒有內置或優雅的方式來做到這一點,而不寫我自己的發電機?是否有一種優雅的方式通過迭代遍歷列表N次(如itertools.cycle但限制循環)?
理想情況下,itertools.cycle(my_list)將有第二個參數來限制它循環的次數...唉,沒有這樣的運氣。
我想通過一個迭代器反覆遍歷一個列表(N次),以免在列表中實際存儲N個列表副本。有沒有內置或優雅的方式來做到這一點,而不寫我自己的發電機?是否有一種優雅的方式通過迭代遍歷列表N次(如itertools.cycle但限制循環)?
理想情況下,itertools.cycle(my_list)將有第二個參數來限制它循環的次數...唉,沒有這樣的運氣。
import itertools
itertools.chain.from_iterable(itertools.repeat([1, 2, 3], 5))
Itertools是一個奇妙的圖書館。 :)
這是一個相當明確的答案,不涉及我自己的生成器/迭代器(儘管馬特安德森的回答顯示這不是太混亂),並且是一個滿足我的問題的第一個答案。所以,我接受它。謝謝!! – JJC 2012-04-26 08:57:02
itertools.chain.from_iterable(iter(L) for x in range(N))
對於需要多次迭代列表的特殊情況,這並不算太壞。
它確實創造n
引用列表來my_list
,所以如果n
是非常大的,最好是用Darthfelt的回答
>>> import itertools as it
>>> it.chain(*[my_list]*n)
我試圖避免在內存中複製列表(或引用它),否則只是:mylist * n將會是足夠的。 :-)儘管如此,感謝您的意見。只需要清楚,通過* list運算符擴展列表並將其乘以n而不是將列表乘以n?是否有區別? – JJC 2012-04-26 13:34:52
@JJC,'mylist * n'用'len(mylist)* n)'元素創建一個列表。對於這個答案,你只需創建一個'n'元素列表,所以根據'len(mylist)'和'n',這可能會產生巨大的差異 – 2012-04-26 22:08:05
我明白[1,2,3,4] * 2會創建一個8個元素的列表。那麼,你說* [1,2,3,4] * 2只創建了兩個元素?對不起,我很困惑。謝謝。 – JJC 2012-04-28 09:36:19
其他所有的答案都非常優秀。另一種解決方案是使用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,因爲技術上我要求一個非自動滾動的發電機,但是如果我可以接受兩個發電機,我也會接受你的(也可能是別人的:-))謝謝! – JJC 2012-04-26 08:52:50
@ Darthfett的答案被記錄爲一個itertools recipes:
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']
我相信乘以一個整數列表是不夠好,對嗎? '[1,2,3] * 4' – C2H5OH 2012-04-26 00:06:42
@ C2H5OH這將創建列表的4個淺拷貝(N個拷貝是不需要的)。 – Darthfett 2012-04-26 00:17:52
@Darthfett:確實。這就是爲什麼它是一個評論。但是你會同意這是最優雅的解決方案:-P – C2H5OH 2012-04-26 00:19:22