当下一个方法应该返回两个生成器的值时,如何为类创建下一个算法



我有下面的例子,其中一个类的下一个方法应该返回来自两个生成器的值:

class Test():
def __next__(self):
g1, g2 = self._gen1(), self._gen2() 
return next(g1), next(g2)
def _gen1(self):
i = 0
while True:
yield i
i += 2
def _gen2(self):
i = 1
while True:
yield i
i += 2

但是,当我为这个类调用next时,值不会递增。

>>> t = Test()
>>> next(t)
>>> (0, 1)
>>> next(t)
>>> (0, 1)

怎么了?有没有比这门课更有说服力的写作方法?

虽然我不知道你想要实现什么,但这里有一个干净的版本,(我认为(可以满足你的需求。

class Test():
def __init__(self):
self.g1 = self._gen2() 
self.g2 = self._gen1()
def __next__(self):
return next(self.g1), next(self.g2)
def _gen1(self):
i = 0
while True:
yield i
i += 2
def _gen2(self):
i = 1
while True:
yield i
i += 2
t = Test()
print(next(t))           
print(next(t))           
print(next(t))  

您的代码不起作用,因为它在每次调用__next__()时都会重新创建生成器函数,这会在返回下一个next()值之前将它们有效地重置回初始状态:

def __next__(self):
g1, g2 = self._gen1(), self._gen2()  # Don't do this here.
return next(g1), next(g2)

您可以通过添加__init__()方法并在其中初始化它们来修复此问题:

class Test:
def __init__(self):
self.g1, self.g2 = self._gen1(), self._gen2()  # Initialize here.
def __next__(self):
return next(self.g1), next(self.g2)
...

同样可以避免问题的一种更雄辩、更简洁的方法是使用内置的zip()函数创建一个"生成器迭代器",每次调用它时都会从每个生成器返回下一对值。另一个优点是,只需更改__init__()方法,就可以很容易地扩展到处理更多的生成器。

我的意思是:

class Test:
def __init__(self):
self.generators = zip(self._gen1(), self._gen2())
def __next__(self):
return next(self.generators)
def _gen1(self):
i = 0
while True:
yield i
i += 2
def _gen2(self):
i = 1
while True:
yield i
i += 2
t = Test()
for _ in range(3):
print(next(t))

输出:

(0, 1)
(2, 3)
(4, 5)

最新更新