迭代器iterator
-
python中实现了
__iter__
方法的对象是可迭代的,实现了next()
方法的对象是迭代器(要实现next()
方法需要在类中实现__iter__
和__next__
方法); -
一个类想被用于
for...in...
循环,类似for i in list:
,就必须实现一个__iter__()
方法,该方法返回一个迭代对象。然后,python
的for
循环就会不断调用该迭代对象的next()
方法拿到循环的下一个值,直到遇到StopIteration
错误时退出循环。 -
分类:
-
In fact this is how the for loop works, if we write
for x in iterator:
<code block>
then the interpretor
- calls
iterator.__next__()
and bindsx
to the result - executr the code bliok
- repeats until a
StopIteration
error occurs
So, that means x = iterator.__next__()
.(迭代器本质上是每次调用__next__()
方法都返回下一个元素或抛出StopIteration
异常的容器对象)
- Formally, an object is iterable if it can be converted to an iterator using the built-in function
iter()
. for
loops work on either iterators or iterables. In the second case, the iterable is converted into an iterator before the loop starts.- One thing to remember about iterators is that they are depleted by use.
"""采用迭代器生成斐波那契数列"""
class Fib(object):
def __init__(self):
self.a = 0
self.b = 1
def __iter__(self):
return self
def __next__(self):
x, y = self.a, self.b
self.a = self.a + self.b
self.b = self.a + self.b
return x, y
# 测试函数
def demo():
fib = Fib()
j = 1
for i in fib:
if j > 50:
raise StopIteration
print(i)
j += 1
# 执行测试函数
if __name__ == '__main__':
demo()
"""创建一个计数器类:迭代器"""
class Count(object):
def __init__(self, max):
self.max = max
self.count = 0
def __iter__(self):
print('__iter__() has been called')
return self
def __next__(self):
x = self.count
if x < self.max:
print('__next__() has been called')
self.count += 1
return x
else:
print('StopIteration has been called')
raise StopIteration
# 定义测试函数
def main():
counter = Count(100)
print('\n=== counter的内容:===')
print(counter)
print('\n=== counter的类型:===')
print(type(counter))
for i in counter:
print(i)
# 执行测试函数
if __name__ == '__main__':
main()
生成器generator
1. 概念
以 list 容器为例,在使用该容器迭代一组数据时,必须事先将所有数据存储到容器中,才能开始迭代;而生成器却不同,它可以实现在迭代的同时生成元素。也就是说,对于可以用某种算法推算得到的多个数据,生成器并不会一次性生成它们,而是什么时候需要,才什么时候生成。
2. 创建
- 定义一个以 yield 关键字标识返回值的函数;
- 调用刚刚创建的函数,即可创建一个生成器。
3.示例
- 一种创建generator的快捷方法:
L = [x * x for x in range(10)] #使用[]创建的是列表对象,存有0-9的平方值
g = (x * x for x in range(10)) #使用()创建的是一个生成器对象
- 采用
yield
关键字创建generator:
def intNum():
print("开始执行")
for i in range(5):
yield i
print("继续执行")
# 生成对象
num = intNum() #num是一个生成器实例
print(num.__next__() ) #对num对象使用方法__next__(),函数运行至“yield i”暂停,输出"开始执行,0"
num.__next__() #从暂停的地方继续执行,输出"继续执行,1"
# 或者使用for...in...直至raise StopIteration error终止循环
for i in num:
print(i)
- 自动触发生成器迭代示例:
import random
def f(n):
i = 1
while i <= n:
yield random.uniform(0,1) < 0.5
i += 1
ff = f(100)
print(sum(ff)) #没有对ff使用for或者next(),sum()函数似乎自动触发了生成器对象ff迭代