迭代器和生成器
list
dic
str
set
tuple
f = open()
range()
enumerate
以上为可迭代对象
print(dir([])) #告诉我列表拥有的所有方法
ret = set(dir([]))&set(dir({}))&set(dir(''))&set(dir(range(10)))
求这些对象拥有的方法
只要是能被for循环的数据类型 就一定拥有__iter__方法
# print([].__iter__())
# 一个列表执行了__iter__()之后的返回值就是一个迭代器
print(set(dir([].__iter__())) - set(dir([]))) #看看迭代器比列表多了什么方法
Iterable 可迭代的 -- > __iter__ #只要含有__iter__方法的都是可迭代的
# [].__iter__() 迭代器 -- > __next__ #通过next就可以从迭代器中一个一个的取值
# 只要含有__iter__方法的都是可迭代的 —— 可迭代协议
迭代器的概念
# 迭代器协议 —— 内部含有__next__和__iter__方法的就是迭代器
# 迭代器协议和可迭代协议
# 可以被for循环的都是可迭代的
# 可迭代的内部都有__iter__方法
# 只要是迭代器 一定可迭代
# 可迭代的.__iter__()方法就可以得到一个迭代器
# 迭代器中的__next__()方法可以一个一个的获取值
# for循环其实就是在使用迭代器
for循环列表时执行时实际调用[].__iter__方法,生成一个新的迭代器,新的迭代器从头开始迭代
迭代器的好处:
# 从容器类型中一个一个的取值,会把所有的值都取到。
# 节省内存空间
#迭代器并不会在内存中再占用一大块内存,
# 而是随着循环 每次生成一个
# 每次next每次给我一个
生成器就是迭代器
#只要含有yield关键字的函数都是生成器函数
# yield不能和return共用且需要写在函数内
def generator(): print(1) yield 'a' print(2) yield 'b' yield 'c' g = generator()
对生成器函数赋值时会生成一个新的生产器
调用一次g.__next__()会返回一个yield的值,
下次调用返回下个yield的值
b = generator()#又生成一个新的生成器调用一次b.__next__()会返回第一个yield的值,而不是继续g生产器的yield的值
所以for循环列表的时候都是从第一个yield执行
for循环g或b时看之前是否调用过生产器,再接着执行。
def wahaha(): for i in range(2000000): yield '娃哈哈%s'%i # g = wahaha() # g1 = wahaha() # print(g.__next__()) # print(g1.__next__()) # g = wahaha() # count = 0 # for i in g: # count +=1 # print(i) # if count > 50: # break # # print('*******',g.__next__()) # for i in g: # count +=1 # print(i) # if count > 100: # break