目录
一. 迭代器
1.可迭代协议&迭代器协议(Iterable/Iterator)
只要是能被for循环的数据类型就一定拥有iter方法
【==可迭代协议(Iterable)==】只要含有iter方法的都是可迭代的(就可以被for循环)
判断是否含有iter方法(是否可以被for循环)
print('__iter__' in dir(dict))
>>> True
for 循环先去找iter方法,找到后开始遍历,如果没找到就报错
for循环实际是在使用迭代器
可以被for循环的东西
list
dict
str
set
tuple
f = open() #文件
range()
enumerate
(可迭代的东西).__iter__() >>> 迭代器
一个列表执行了iter()之后的返回值就是一个迭代器
[].__iter__() #迭代器
迭代器包含·的方法有:
#【1】__setstate__
#【2】__next__ #通过next可以从迭代器中一个一个的取值
#【3】__length_hint__
[0,1].__iter__().__length_hint__() #元素个数
>>> 2
【==迭代器协议(Iterator)==】内部同时含有next和iter方法的就是迭代器
from collections import Iterator
class A:
def __iter__(self): pass
def __next__(self): pass
a = A()
print(isinstance(a, Iterator))
>>> True
模拟for循环
list1 = [1,2,3,4]
iterator = list1.__iter__()
while True:
print(iterator.__next__())
2.迭代器的好处
从容器类型中一个一个的取值,会把所有值都取到
节省内存空间
迭代器并不会在内存中再占用一大块内存
而是随着循环 每次生成一个
每次next每次给我一个
range(10000000000) #类似定义,但还未读取占空间
print(list(range(10000000000)))
二. 生成器(自己写的迭代器)
1.生成器函数(自己写的函数)
含有yield关键字的函数,是生成器函数
特点:
调用函数之后,函数不执行,返回一个生成器
每次调用next方法的时候会取到一个值
直到取完最后一个,再执行next会报错
yield不能与return共用,且需要写在函数内部
return会会结束
yelid后不会结束
def generator(): #1.定义生成器函数
print(1)
yield