学习python的过程中,迭代器与生成器是绕不开的话题, 什么是迭代器和生成器呢?
1、迭代和它的小伙伴们。
迭代,顾名思义就是不停的重复,但是总有累了结束的时候,来个小迭代感受一下。
#不停的获得列表A中的成员,等全部获得了就结束了
A = [1,2,3,4]
for i in A:
print(i)
这里list A 就是可迭代的对象,就是说list具有可以迭代的功能,也可以说,list实现了python中规定的迭代协议。
那么什么是python中规定的可迭代协议呢?
python 说:如果你能实现__iter__方法,并且返回一个可迭代的迭代器,我就说你是可迭代的对象。
class selfdef():
def __iter__(self):
return selfiterator #这里selfiterator是一个可迭代的迭代器
......
那么什么是python中规定的迭代器呢?因为selfiterator实现了__next__方法,就称它为迭代器,所以迭代器协议就是对象实现了__next__方法。满足迭代器协议的称之为迭代器。
class selfiterator():
def __init__(self):
self.name = 'this is a iterator'
self.num = 0
def __next__(self):
i = self.num
if i > 10:
self.num -= 1
return i
else:
raise StopIteration
for item in obj 这是python的语法糖,如果obj 是一个可迭代对象,它自动实现了先调用iter函数将其转为迭代器,然后对迭代器不断调用next方法,并将获取的值赋予item,并自动处理异常。
让我们分析一下list 来加深印象
list 可以像下面这样来用,说明它是可迭代的对象,满足可迭代协议,即内部实现了__iter__方法,返回了一个可迭代的迭代器
list =[1,2,3,4]
for item in list
print (item)
class List:
def __iter__(self):
return iter(self) #调用了self.__iter()__函数返回底层的迭代器对象,该对象实现了__next__方法
list 是可迭代的对象,但它并不是可迭代的迭代器,因为它本身并没有实现next方法,并不能通过next(list)来调用。
迭代器总结
1.对象-》实现iter方法变为可迭代对象-》实现next方法变为可迭代的迭代器
2.for…in…语法糖,自动实现了调用 iter 与 next
2、生成器-特殊的迭代器
python 中提供了2中迭代器生成方法
(1)列表表达式转化
a = [x for x in range(5)] #[0,1,2,3,4]
b= (x for x in range(5)) #generator object
(2)生成器函数
#普通函数使用yield 代替return 函数变为生成器函数
#当调用这个“函数”的时候,它会立即返回一个迭代器,而不立即执行函数内容,直到调用其返回迭代器的next方法是才开始执行,直到遇到yield语句暂停。
#生成器自动实现了迭代器协议 ,因此可以调用它的next方法
def count(n):
while n > 0:
yield n
n -=1
cal = count(10) #返回一个迭代器
next(cal) #10
next(cal) #9
#或者仍使用语法糖
for i in count(10)
print(i)
生成器的作用
(1)生成器主要是为简化使用迭代器而生,生成器函数简化了迭代器的实现,不用去实现复杂的iter与next函数,只需要一个yield:
(2)生成器实现了延迟执行,在进行大数据计算是节约大量内存,对比一下两个计算方法
a = sum([x for x in range(10000)]) #需要分盘生成存储10000个数的列表的内存
b = sum(x for x in range(10000)) #使用迭代器协议访问生成器对象,不需要预先全部生成列表
(3)python 通过生成器实现了协程,即实现了单线程内,不同任务函数之间的协同工作。关于协程的使用我预计在下一部分结合进程线程进行学习总结。