我是Python的新手,正在阅读Python Tricks一书。在关于生成器的章节中,给出了以下示例(进行了一些更改)
git for-each-ref
之后,我编写一个循环,实例化生成器并打印值:
int smallest=Integer.MAX_VALUE;//assume smallest to be largest integer
for(int i=0;i<100;i++){
int num=sc.nextInt();//this will run 100 times and hence will input 100 number
if(num<smallest){//if number is smaller than smallest then num is smallest
smallest=num;
}
}
System.out.println(smallest);
为什么我必须在循环内调用class BoundedGenerator:
def __init__(self, value, max_times):
self.value = value
self.max_times = max_times
self.count = 0
def __iter__(self):
return self
def __next__(self):
if self.count < self.max_times:
self.count += 1
yield self.value
?
我(认为)我知道在循环行定义中将调用for x in BoundedGenerator('Hello world', 4):
print(next(x))
函数,并且在每次迭代中都将调用next(X)
,但是我不明白为什么必须调用下一个再次进入循环。这不是多余的吗?
如果我不调用__iter__
函数,则循环将永远运行。
答案 0 :(得分:4)
由于使用__next__
,您的yield
方法本身是生成器函数。它必须是使用return
的常规函数。
def __next__(self):
if self.count < self.max_times:
self.count += 1
return self.value # return to provide one value on call
raise StopIteration # raise to end iteration
迭代时,python调用iter.__next__
来接收新值。如果这是一个生成器函数,则调用仅返回一个生成器。这与其他任何生成器函数的行为相同:
>>> def foo():
... yield 1
...
>>> foo()
<generator object foo at 0x106134ca8>
这需要您在生成器上调用next
才能真正获取值。同样,由于您将BoundedGenerator.__next__
定义为生成器函数,因此每个迭代步骤仅提供一个新的生成器。
使用return
而不是yield
实际上会返回该值,而不是生成该值的生成器。此外,完成后应该raise StopIteration
-这表示迭代已结束。