迭代器
迭代是Python最强大的功能之一,是访问元素集合的一种方法。
迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束,迭代器只能向前不会后退。
迭代器有两个基本方法,iter()和next()。
字符串,列表,或元组对象都可以用于创建迭代器。
迭代器对象可以使用常规语句for进行遍历:
使用next()函数:
#next.py import sys list = [1,2,3,4] it = iter(list) while True: try: print(next(it)) except StopIteration: sys.exit()
运行结果:
robot@ubuntu:~/wangqinghe/python/20190827$ python3.5 next.py
1
2
3
4
创建一个迭代器:
把一个类作为一个迭代器使用需要在类中实现两个方法__iter__()与__next__().
类都是由一个构造函数,Python的构造函数为__init__(),它会在对象初始化的时候执行。
__iter__方法返回一个特殊的迭代器对象,这个迭代器对象实现了__next__()方法通过StopIteration异常标识迭代的完成。
__next__()方法会返回下一个迭代器对象。
#iter.py class MyNumbers: def __iter__(self): self.a = 1 return self def __next__(self): x = self.a self.a += 1 return x myclass = MyNumbers() myiter = iter(myclass) print(next(myiter)) print(next(myiter)) print(next(myiter)) print(next(myiter)) print(next(myiter)) print(next(myiter))
运行结果:
robot@ubuntu:~/wangqinghe/python/20190827$ python3.5 iter.py
1
2
3
4
5
6
StopIteration
StopIteration异常用于标识迭代的完成,防止出现无限循环的情况,在__next__方法种我们可以设置在完成指定循环次数后触发StopIteration异常来结束迭代。
在20次迭代后停止执行:
#stop.py class MyNumbers: def __iter__(self): self.a = 1 return self def __next__(self): if self.a <= 20: x = self.a self.a += 1 return x else: raise StopIteration myclass = MyNumbers() myiter = iter(myclass) for x in myiter: print(x)
运行结果:
robot@ubuntu:~/wangqinghe/python/20190827$ python3.5 stop.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
生成器:
在Python中,使用了yield的函数被称为生成器(generator)。
跟普通函数不同,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
在调用生成器运行过程中,每次遇到yield时函数会暂停并保持当前所有运行信息,返回yield的值,并在下一次执行next()方法时从当前位置继续运行。
调用一个生成器函数,返回的是一个迭代器对象。
#yield.py import sys def fibonacci(n): a,b,counter = 0,1,0 while True: if(counter > n): return yield a a,b = b,a+b counter += 1 f = fibonacci(10) while True: try: print(next(f),end=" ") except StopIteration: sys.exit()
运行结果:
robot@ubuntu:~/wangqinghe/python/20190827$ python3 yield.py
0 1 1 2 3 5 8 13 21 34 55
什么时候需要用到yield
一个函数f,返回一个list,这个list是动态计算出来的,并且这个list会很大,这个时候我们希望每次调用这个函数并使用迭代器进行循环的时候,一个一个的得到每个list的值,而不是直接得到一个list来节省内存,这个时候yield就很有用。