可迭代对象:内部含有‘__iter__’方法的对象
存储的数据可以直接显示,比较直观
拥有的方法比较多
缺点:
占用内存
不能直接for循环取值,是通过内部转化成迭代器
# dir():获取一个对象的所有方法 s1 = 'abcde' print(dir(s1)) # 输出一个list,内容是s1对象的所有方法,每个方法以字符串形式输出 print('__iter__' in dir(s1)) # 判断一个对象是否是可迭代对象
''' 迭代器:内部含有'__iter__'并且含有'__next__'方法的对象就是迭代器 因为迭代器的内部含有'__next__'方法,所有可以通过for循环取值 判断一个对象是否是迭代器:'__iter__' in dir(f1) and '__next__' in dir(f1) 利用iter(object)/object.__iter__()形成一个迭代器,对迭代器进行操作可以节省内存 利用next(object)/object.__next__()取值,一次只取一个 迭代就是数据处理的基石,扫描内存中放不下的数据集时,我们要找到一种惰性获取数据项的方式,即按需一次获取一个数据项,这就是迭代器模式 优点: 节省内存 惰性机制:next一次取一个值,下一次next再取下一个值 缺点: 不能直观的查看里面的数据 速度慢 取值不能回头 '''
s = [11,22,33,44] obj = s.__iter__() # 等同于iter(s),利用s形成一个迭代器,赋值给obj print(s) # [11, 22, 33, 44] print(obj) #s = [11,22,33,44] obj = s.__iter__() print(obj.__next__()) # 11,等同于next(obj),迭代器利用 '__next__()'方法取值,一次只取一个值 print(next(obj)) # 22 print(obj.__next__()) # 33 # 利用while循环 模拟for循环对可迭代对象取值 s = [11,22,33,44,55,66,77,88] obj = iter(s) while 1: try: print(next(obj)) except StopIteration: break s = [11,22,33,44,55,66,77,88,99] obj = iter(s) for i in range(4): print(next(obj)) for j in range(4): print(obj.__next__())
生成是我们自己用python代码构建的数据结构,迭代器是python提供的,或者转化来的
获取生成器三种方式:
通过生成器函数自己写
通过生成器表达式自己写
python内部提供
# 只要函数中有 yield,那么它就是生成器函数,一个生成器函数可以存在多个yield # yield不会结束函数的执行,只是暂停函数 def fun(): print(111) yield 3 # 一个next(),代码就会执行到这里,并且将3返回,后面的代码不执行,直到下一个next() print(222) yield 4 ret = func() # 因为函数中有yield,所以是生成器函数,所以这里并不会执行函数中的代码 print(ret) #生成器对象 print(next(ret)) # 111 3 生成器中一个next,对应一个yield, print(next(ret)) # 第一个yield执行完,就会执行这里的next,接着执行函数中第一个yield后面的代码
# 吃包子例子 def func(): for i in range(1,50): yield f'{i}号包子' ret = func() for i in range(10): print(next(ret))
def func(): l1 = [1,2,3,4,5] yield l1 ret = func() print(ret) #print(next(ret)) # [1, 2, 3, 4, 5] def func1(): l2 = [1,2,3,4,5] yield from l2 # yield from 将list 变成一个生成器 ret = func1() # 返回一个生成器对象赋值给ret for i in ret: # 利用for循环对生成器对象直接取值, print(i) def func(): list1 = [1,2,3,4,5] list2 = [6,7,8,9,0] yield from list1 yield from list2 ret = func() for i in ret: print(i) # 1 2 3 4 5 6 7 8 9 0
ret = (i for i in range(1,11)) print(ret) #at 0x00000000023E8570> for i in ret: print(i)
让生成器产出值的三种方式:next(),for循环,list(),本质都是调用next()
# list(generator) ,将生成器对象转化成list def chain(*iterables): for it in iterables: for i in it: yiled i ret = chain('abc',(1,2,3)) print(ret) #print(list(ret)) # ['a', 'b', 'c', 0, 1, 2] def chain(*iterables): for it in iterables: yield from it ret = chain('abc',(1,2,3)) print(list(ret)) # ['a', 'b', 'c', 0, 1, 2]