复制一个itertools循环对象

时间:2016-05-26 16:14:31

标签: python itertools

我想制作function对象的浅表副本,但我不知道如何,因为它没有内置复制方法。我想实现类似下面的内容,我在其中创建一个循环的副本,迭代它几次,然后再次复制原始,并从循环的开始再次迭代 >

itertools.cycle

5 个答案:

答案 0 :(得分:2)

可能需要一些重构,但工厂在这里可以很好地工作。

from itertools import cycle

cycle_factory = lambda: cycle('1234')

c1 = cycle_factory()
print next(c1) # 1

c2 = cycle_factory()
print next(c2) # 1

否则,我不确定您是否能够满足每次在周期开始时开始的标准。基于类的接近也会起作用,但需要更多的开销。

itertools.tee方法的一个问题是它会在tee-d迭代器停止而不是从头开始的情况下继续迭代。因此,你必须在开始时开球。如果您无法控制循环的生成方式,这可能是唯一的选择。

答案 1 :(得分:1)

复制循环本身会遇到问题。例如,copy.copying it doesn't produce independent copies

我建议您不要尝试复制循环,而是从原始对象重新创建它:

new_cyc = itertools.cycle(c)

如果您创建原始循环的对象是迭代器,则不能只重复调用cycle。而是在第一次调用cycle之前创建一个列表,并保留列表:

c_list = list(c)
cyc = itertools.cycle(c_list)

# later
new_cyc = itertools.cycle(c_list)

如果您创建原始循环的对象是可能是也可能不是无限的迭代器,则无法安全地在其上调用list。相反,您可以在创建周期之前tee 当您需要进行新周期时copy.copy未成熟的T恤。 (tee支持复制。)

c_tee, c_tee2 = itertools.tee(c)
cyc = itertools.cycle(c_tee2)

# Copy c_tee, not the c_tee2 we already used.
new_cyc = itertools.cycle(copy.copy(c_tee))

所有这些都假定您控制循环的创建。如果您从其他地方收到一个循环,您可能无法访问它循环的对象。在这种情况下,您最好的选择是tee周期本身。如果您需要经历循环的多个循环,这可能会很昂贵:

cyc_master, cyc1 = itertools.tee(cyc)
# Use cyc1

# Later
cyc2 = copy.copy(cyc_master)

答案 2 :(得分:1)

您可以创建自定义类来执行您想要的操作:

import itertools

class CopyCycle:
    def __init__(self, iterable):
        self.iterable = iterable
        self._cycle = itertools.cycle(self.iterable)

    def cycle(self):
        return self

    def __iter__(self):
        return self

    def next(self):
        return self._cycle.next()

    def __next__(self):  #Python 3+
        return self._cycle.next()

    def copy(self):
        return CopyCycle(self.iterable)


if __name__ == '__main__':
    cyc = CopyCycle("ABCD").cycle()
    for i in range(5):
        print(next(cyc))

    cyc_copy = cyc.copy()
    for i in range(2):
        print(next(cyc_copy))
    cyc_copy = cyc.copy()
    for i in range(2):
        print(next(cyc_copy))

输出:

A
B
C
D
A
A
B
A
B

答案 3 :(得分:0)

copy应该这样做:

>>> from copy import copy
>>> cyc_copy = copy(cyc)
>>> next(cyc_copy)
'A'
>>> next(cyc_copy)
'B'
>>> cyc_copy = copy(cyc)
>>> next(cyc_copy)
'A'
>>> next(cyc_copy)
'B'

答案 4 :(得分:0)

方法1:制作两个itertools.cycle个对象

import itertools
c = 'ABCD'
cyc1 = itertools.cycle(c)
cyc2 = itertools.cycle(c)
for _ in range(2): print(next(cyc1))  # prints A\nB\n
for _ in range(2): print(next(cyc2))  # prints A\nB\n



<script src="//repl.it/embed/IRcx/0.js"></script>
&#13;
&#13;
&#13;

[首选解决方案]方法2:使用itertools.tee

拆分为n个迭代器
import itertools
cyc = itertools.cycle('ABCD')
cyc1, cyc2 = itertools.tee(cyc, 2)
for _ in range(2): print(next(cyc1))  # prints A\nB\n
for _ in range(2): print(next(cyc2))  # prints A\nB\n

&#13;
&#13;
<script src="//repl.it/embed/IRcx/2.js"></script>
&#13;
&#13;
&#13;

使用copy函数使用copy.copy模块进行警告

不会按预期创建迭代器的副本。

import itertools, copy
cyc = itertools.cycle('ABCD')
cyc1 = copy.copy(cyc)
cyc2 = copy.copy(cyc)
for _ in range(2): print(next(cyc1))  # prints A\nB\n
for _ in range(2): print(next(cyc2))  # prints C\nD\n

&#13;
&#13;
<script src="//repl.it/embed/IRcx/3.js"></script>
&#13;
&#13;
&#13;

使用copy模块的解决方法:可能的解决方法是使用copy.deepcopy函数。

import itertools, copy
cyc = itertools.cycle('ABCD')
cyc1 = copy.deepcopy(cyc)
cyc2 = copy.deepcopy(cyc)
for _ in range(2): print(next(cyc1))  # prints A\nB\n
for _ in range(2): print(next(cyc2))  # prints A\nB\n

&#13;
&#13;
<script src="//repl.it/embed/IRcx/4.js"></script>
&#13;
&#13;
&#13;