1)python的迭代器协议
问题:
1)迭代协议
__iter__
__next__
2)迭代器是什么?
迭代器是访问集合内元素的一种方式,一般用来遍历数据。迭代器和以下标访问的方式不一样,迭代器是不能返回的,迭代器提供了一种惰性方式访问数据。迭代器是实现了迭代协议 __iter__方法。
迭代器与可迭代对象的区别
我们查看下Iterator与Iterable类中分别实现了哪些协议。
只要实现了__iter__方法就是可迭代类型,迭代器必须也实现__next__方法。
class Iterable(metaclass=ABCMeta):
__slots__ = ()
@abstractmethod
def __iter__(self):
while False:
yield None
@classmethod
def __subclasshook__(cls, C):
if cls is Iterable:
return _check_methods(C, "__iter__")
return NotImplemented
__class_getitem__ = classmethod(GenericAlias)
class Iterator(Iterable):
__slots__ = ()
@abstractmethod
def __next__(self):
'Return the next item from the iterator. When exhausted, raise StopIteration'
raise StopIteration
def __iter__(self):
return self
@classmethod
def __subclasshook__(cls, C):
if cls is Iterator:
return _check_methods(C, '__iter__', '__next__')
return NotImplemented
from collections.abc import Iterator,Iterable
lis = [1,2]
print(isinstance(lis,Iterable))
print(isinstance(lis,Iterator))
--------------------------------------------------
True
False
因为list只实现了 __iter__协议(Iterable),而没有实现__next__协议(Iterator)
from collections.abc import Iterator,Iterable
lis = [1,2]
iter_lis = iter(lis)
print(isinstance(lis,Iterable))
print(isinstance(iter_lis,Iterator))
-----------------------------------------
True
True
from collections.abc import Iterator,Iterable
class Myiterator(Iterator):
def __init__(self,employ_list):
self.employs_iter = employ_list
self.index = 0
#继承了Iterator就不用再实现
# def __iter__(self):
# pass
def __next__(self):
try:
words = self.employs_iter[self.index]
except IndexError:
raise StopIteration
self.index += 1
return words
if __name__ == '__main__':
Myiterator = Myiterator(['a','b','c'])
while True:
try:
print(next(Myiterator))
except Exception:
pass
------------------------------------------------
a
b
c
2)python生成器
1、 什么是生成器函数
只要又yield关键字就是生成器函数。
def gen_fun():
yield 1
def fun():
return 1
#生成器对象
gen = gen_fun()
fun = fun()
print(type(gen))
print(type(fun))
-------------------------------------
<class 'generator'>
<class 'int'>
def gen_fun():
yield 1
yield 2
gen = gen_fun()
for item in gen:
print(item)
--------------------------------------------
1
2
通过一个例子来看下yield关键字
生成一组斐波那契数组
eg: [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
def fib(index):
re_list = []
n,a,b = 0,0,1
while n < index:
re_list.append(b)
a,b = b,a+b
n += 1
return re_list
print(fib(99999))
-----------------------------------
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 14.....
import time
def fib(index):
n,a,b = 0,0,1
while n < index:
yield b
a,b = b,a+b
n += 1
time1 = time.time()
for item in fib(99999):
print(item)
time2 = time.time()
-------------------------------------
采用yield关键字不消耗过多内存