迭代器
概念: 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完
可迭代对象:一般来说可以用for进行遍历的就是可迭代对象,例如:list,tuple等类型都是迭代器
实例:
1、创建一个类,该类包含__iter __魔法方法就是可迭代对象
2、一个类中含有__iter__和__next__两个魔法方法就是迭代器
测试1:
##迭代器测试
from collections.abc import Iterable
from collections.abc import Iterator
class Classmate(object):
def __iter__(self):
pass
classmate = Classmate()
print('是否为可迭代对象',isinstance(classmate,Iterable))
结果:
是否为可迭代对象 True
测试2:
##迭代器测试
from collections.abc import Iterable
from collections.abc import Iterator
class Classmate(object):
def __iter__(self):
pass
def __next__(self):
pass
classmate = Classmate()
print('是否为可迭代器',isinstance(classmate,Iterator))
那么上面创建的迭代器如何使用呢:
测试
##迭代器测试
from collections.abc import Iterable
from collections.abc import Iterator
class Classmate(object):
def __init__(self):
self.numbers = [1,2,3,4]
self.current_count = 0
def __iter__(self):
return self#可迭代对象__iter__的返回值要求是一个实例化对象,并且该对象有__iter__和__next__方法,所以刚好选择自身
def __next__(self):
if self.current_count < len(self.numbers):
#判断是否为自生的最后一个元素
ret = self.numbers[self.current_count]
self.current_count +=1
return ret
else:
raise StopIteration #结束迭代器
classmate = Classmate()
for each_num in classmate:
print(each_num)
特点:如果一个对象是迭代器,那么一定是可迭代对象
迭代器的优点
占用极小的内存,实现功能
举例说明占用内存小:
##常规方法打印斐波那契数列
def fib(countAll):
a,b = 0, 1
count = 0
k = []#存放所有的数据
while True:
if count < countAll:
k.append(a)
count += 1
a, b = b, a+b
else:
break
return k
f = fib(3)
print(f)
##用迭代器实现斐波纳契
class Fibonacci(object):
def __init__(self, all_num):
self.all_num = 10
self.a = 0
self.b = 1
self.current_num = 0
def __iter__(self):
return self
def __next__(self):
if self.current_num < self.all_num:
ret = self.a
self.a, self.b = self.b, self.a + self.b
self.current_num += 1
return ret
else:
raise StopIteration
fib = Fibonacci(10)#生成十个
for num in fib:
print(num)
生成器:带有yield 的函数就是生成器,生成器是一种特殊的迭代器
作用:可以实现多任务同时进行
使用
import time
def test1():
while True:
print('===working__test1====')
time.sleep(0.4)
yield
def test2():
while True:
print('===working__test2====')
time.sleep(0.4)
yield
def main():
t1 = test1()#生成一个生成器
t2 = test2()#生成一个生成器
while True:
next(t1)#执行一次函数
next(t2)
if __name__ == '__main__':
main()
生成器的特点:
1、yield 类似与return ,但是不会重新执行函数,只会在上一次终止的地方开始执行
2、不仅仅是next()启动生成器,通过send来启动生成器,生成器.send(None)类似于next(obj),但是可以传参数,传过去的参数可以作为 yield的返回值