2010-09-29 33 views
5

對於我正在處理的一個小項目,我需要遍歷一個列表。對於這個循環的每個元素,我必須通過同一個列表開始另一個循環,將前一個元素作爲新循環的第一個元素。例如,我想能夠生產這樣的事情:複製可迭代對象的Python方法

1, 2, 3, 4, 1, 2, 3, 4, 1, ... 
2, 3, 4, 1, 2, 3, 4, 1, 2, ... 
3, 4, 1, 2, 3, 4, 1, 2, 3, ... 
4, 1, 2, 3, 4, 1, 2, 3, 4, ... 
1, 2, 3, 4, 1, 2, 3, 4, 1, ... 
... 

我認爲每一個。接下來(後複製itertools.cycle)將保存當前狀態,這樣我就可以開始新的週期與來自「外部」循環的元素相關聯。甚至「重置循環指針」到更舊的位置。我試過如下:

>>> import itertools, copy 
>>> a = itertools.cycle([1, 2, 3, 4]) 
>>> b = copy.copy(a) 

,但得到這個錯誤:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python2.6/copy.py", line 95, in copy 
    return _reconstruct(x, rv, 0) 
    File "/usr/lib/python2.6/copy.py", line 323, in _reconstruct 
    y = callable(*args) 
    File "/usr/lib/python2.6/copy_reg.py", line 93, in __newobj__ 
    return cls.__new__(cls, *args) 
TypeError: cycle expected 1 arguments, got 0 

我知道有很多不同的方式來實現我想要什麼,但我在尋找一些短期的,明確的和Python的代碼。也許有人有另一個想法,甚至一個片段?這是not possible to copy iterator objects喚醒了我的興趣。在需要迭代迭代的情況下,是否有最佳實踐?或者正在複製一些愚蠢無用的迭代?

+1

他們並不傻,[PEP 323](http://www.python.org/dev/peps/pep-0323/)考慮製作可複製的迭代器。 – Matt 2012-11-06 20:06:29

回答

5

Is there a best-practice in situations where one wants a copy of an iterable?

itertools.tee給你兩個迭代器,每個產生相同的項目,如原來的,但需要原件和記住它產生的一切,所以你不能使用原來的了。儘管如此,它仍然無法幫助,因爲它會一直記住這些循環值,直到出現MemoryError。

Or is copying iterables silly and useless in general?

迭代器剛定義爲具有當前狀態併產生一個項目。你不能說出他們將來是否會產生相同的物品,或者他們過去會產生哪些物品。一個真正的副本將不得不這樣做,所以這是不可能的!

在你的情況下,做一個新的循環,我寧願這樣做,而不是試圖複製一個現有的。例如:

def new_cycle(seq, last=None): 
    if last is None: 
     return cycle(seq) 
    else: 
     it = cycle(seq) 
     while next(it) != last: 
      pass 
     return it