Pythonic复制可迭代对象的方法

ato*_*ter 5 python copy cycle python-itertools

对于我正在研究的小项目,我需要循环查看列表.对于这个循环的每个元素,我必须通过相同的列表开始另一个循环,前一个元素作为新循环的第一个元素.例如,我希望能够生成这样的东西:

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, ...
...
Run Code Online (Sandbox Code Playgroud)

我认为在每个.next()之后复制一个itertools.cycle会保留当前状态,这样我就可以用"外部"循环中的元素开始新的循环.甚至"将循环指针"重置为较旧的位置.我尝试了以下方法:

>>> import itertools, copy
>>> a = itertools.cycle([1, 2, 3, 4])
>>> b = copy.copy(a)
Run Code Online (Sandbox Code Playgroud)

但得到了这个错误:

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
Run Code Online (Sandbox Code Playgroud)

我知道有很多不同的方法来实现我想要的东西,但我正在寻找一些简短,清晰和pythonic的代码.也许有人有另一个想法甚至是一个片段?无法复制迭代器对象的事实唤起了我的兴趣.在需要可复制副本的情况下,是否存在最佳实践?或者复制迭代愚蠢和无用?

Joc*_*zel 5

在需要可复制副本的情况下,是否存在最佳实践?

itertools.tee给你两个迭代器,每个迭代器产生与原始项目相同的项目,但它需要原始文件并记住它产生的所有内容,因此你不能再使用它了.虽然它没有帮助,因为它会继续记住这些循环值,直到你得到MemoryError.

或者复制迭代愚蠢和无用?

迭代器只是定义为具有当前状态并产生一个项目.您无法判断他们将来是否会产生相同的物品,或者他们过去会产生哪些物品.真正的副本必须要做到这两点,所以这是不可能的!

在你的情况下,制作一个我宁愿做的新循环,而不是尝试复制现有的循环是如此微不足道.例如:

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