Pet*_*ter 3 python iterator generator
我一直在寻找一种编写基于生成器的Python迭代器的好方法.我发现了很多关于迭代器主题的教程,很多关于生成器和yield语句的教程,但没有结合这两者的内容.我已经构建了一个有效的小例子,并想知道是否有更好的方法来做到这一点.
class myIterator :
def __init__(self, n) :
self.last = n
self.myGen = self.myGenerator()
def __iter__(self) :
return self.myGenerator()
def next(self) :
return self.myGen.next()
def myGenerator(self) :
prev = 0
fib = 1
while fib < self.last :
res = fib
yield res
fib = fib + prev
prev = res
raise StopIteration
Run Code Online (Sandbox Code Playgroud)
我在真实世界的程序中使用了这种技术,可以在我的Github存储库中的SQLStatements.py中找到
最令人困惑的部分是定义next()函数.显而易见的解决方案在每次调用时都返回了第一个元素.存储包含生成器的实例变量有效,但似乎是一个kludge.
如果你知道一个更好的方法来做这个或一个涵盖这个主题的好教程,请告诉我.
编辑:@MartijnPieters发布的第三个例子完全解决了这个问题.保存self.next中的self.generator.next函数提供了下一个函数.我希望这有助于其他人试图解决这个问题.
迭代器协议由两部分组成.该__iter__方法是最重要的方法,当您iter()在对象上使用时,它应该返回迭代器.
只需更换的身体__iter__用myGenerator; 无需提出StopIteration:
class myIterator:
def __init__(self, n):
self.last = n
def __iter__(self):
prev = 0
fib = 1
while fib < self.last:
res = fib
yield res
fib += prev
prev = res
Run Code Online (Sandbox Code Playgroud)
现在iter(myIterator(10))是一个迭代器并且有一个.next()方法.
如果希望您的类直接用作迭代器,则需要__iter__返回self并提供.next()方法.
一个.next()方法为每个函数体生成一个元素(并使用return somevalue).生成器只是一个函数yield,实际上,这样的方法本身为你实现了迭代器协议(包括.next()).
如果您要使用.next()它,它将看起来像这样:
class myIterator:
def __init__(self, n):
self.last = n
self.prev = 0
self.fib = 1
def __iter__(self):
return self
def next(self):
if self.fib < self.last:
res = self.fib
self.fib += self.prev
self.prev = res
return res
raise StopIteration
Run Code Online (Sandbox Code Playgroud)
或者您可以重复使用.next()您的生成器的方法:
class myIterator:
def __init__(self, n):
self.last = n
self.next = self.myGenerator().next # Use the generator `.next`
def __iter__(self):
return self
def myGenerator(self):
prev = 0
fib = 1
while fib < self.last:
res = fib
yield res
fib += prev
prev = res
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
257 次 |
| 最近记录: |