Day 11 迭代器、生成器
迭代器
可迭代对象:str list dict,tuple,set,range()
可迭代对象满足可迭代协议,即内部含有__iter__()方法
判断可迭代对象?
1.查看__iter__()方法在不在对象内
dic = {'name':'alex'} print('__iter__' in dir(s1)) print('__iter__' in dir(dic))
2.函数法
from collections import Iterable from collections import Iterator print(isinstance('alex',Iterable)) # True print(isinstance('alex',Iterator)) # True 返回True即为可迭代对象
迭代器:
对象内部含有__iter__方法且含有__next__方法就是迭代器.
可迭代对象vs迭代器
1, 可迭代对象不能取值,迭代器是可以取值的。
2, 迭代器非常节省内存。
3,迭代器每次只会取一个值。(__next__方法取值。)
4,,迭代器单向的,一条路走到头
lis = [1, 2, 3] # 可迭代对象 ite1 = lis.__iter__() #迭代器 print(ite1.__next__()) #取值,一次取一个 print(ite1.__next__()) print(ite1.__next__()) print(ite1.__next__())
利用while循环模拟for循环
s1 = 'abcdef' iter1 = s1.__iter__() while 1: try: print(iter1.__next__()) except StopIteration: break
生成器
使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行
def func1(x): x += 1 yield x x += 2 yield x x += 3 yield x g1 = func1(5) print(g1.__next__()) # 一个next对应一个yield print(g1.__next__()) print(g1.__next__()) print(g1.__next__()) # StopIteration
生成器直接创建,不需要转化,从源头上节省了内存
send
send 与next一样,也是对生成器取值(执行一个yield)
send可以给上一个yield传值
第一个必须是next开头
最后一个yield永远也得不到send传的值
def func1(): count = yield 6 print(count) count1 = yield 7 print(count1) yield 8 g = func1() next(g) g.send('aaa') g.send('bbb') g.send('ccc') StopIteration
列表推导式与生成器表达式
列表推导式
1.循环模式 [变量(加工后的变量) for 变量 in iterable]
l1 = [i for i in range(1,10)] print(l1) l2 = [i**2 for i in range(1,11)] print(l2)
2.筛选模式[变量(加工后的变量) for 变量 in iterable if 条件]
l3 = [i for i in range(1,31) if i % 3 == 0] print(l3) g = (i for i in range(101)) print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__()) for i in range(50): print(g.__next__()) for i in range(30): print(g.__next__())
生成器表达式
只需将列表表达式中的[ ]换成()即可。