我想制作function
对象的浅表副本,但我不知道如何,因为它没有内置复制方法。我想实现类似下面的内容,我在其中创建一个循环的副本,迭代它几次,然后再次复制原始,并从循环的开始再次迭代 >
itertools.cycle
答案 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.copy
ing 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;
[首选解决方案]方法2:使用itertools.tee
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
<script src="//repl.it/embed/IRcx/2.js"></script>
&#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
<script src="//repl.it/embed/IRcx/3.js"></script>
&#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
<script src="//repl.it/embed/IRcx/4.js"></script>
&#13;