迭代器和生成器

生成器:

  可以理解为一种数据类型,可自动实现迭代器协议,可以理解为生成器就是可迭代对象(其他数据类型可调用内置地__iter__(),如果没有内置的__iter__(),即不可迭代)

  状态挂起:使用yield语句返回一个值。使该函数挂起该生成器函数的状态,保留信息,以便之后从它离开的地方继续执行

 优点:延迟计算 一次返回一个结果 ,等待下次需要再继续返回结果(处理较大的数据可以使用  )

迭代器:

迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项 要么引起一个StopIteration异常,以终止迭代(只能往后走 不能往前退)
可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter()__方法
协议:协议是一种约定,可迭代对象实现了迭代器协议(for sum min max 使用迭代器协议访问对象)

 

1.生成器函数:

  使用yield函数并非return语句

def test() 
    yield 1 #可多个返回值 return只能一个
    yield 2
    yeild 3
print(test())
g=test()#g:生成器 自动实现迭代器协议
print(g.__next__())

 

1 # iter_l =x.__iter__()#遵循迭代器协议,生成可迭代对象
2 # print(iter_l.__next__())#for循环和索引没关系 基于迭代器机制
3 # python 中for循环的强大之处在于可以遍历序列和非序列类型 例如文件
4 f = open('字节方式与文件','r+',encoding='utf-8')
5 text_f =f.__iter__()
6 print(text_f.__next__(),end='')
7 print(text_f.__next__())
8 print(text_f.__next__())

 

补充知识:三元表达式:

name='guoguo'

'TT' if name=='guoguo' else 'FF'【三元表达式】【如果name=guoguo 则返回TT 否则返回FF】

  赋值给result得到结果

  result=‘TT’ if name=='guoguo' else 'FF'

  print(result)

补充知识:列表解析:(缺点:生成列表 放入内存中 若该列表过大则占用内存较大

缺点:占用内存大、效率低
1
egg_list = [] 2 for i in range(10): 3 egg_list.append('鸡蛋%s',%i) 4 print(egg_list) 5 6 列表解析: 7 l = ['鸡蛋%s' %i for i in range(10)]
l = ['鸡蛋%s' %i for i in range(10) if i>5]#三元表达式:'鸡蛋%s' %i  for i in range(10)  if i>5
 l = ['鸡蛋%s' %i for i in range(10) if i>5 else ]#错误 没有四元表达式
8 print(l)

 生成器表达式:

1 laomuji=('鸡蛋%s' %i for i in range(10))#生成器表达式(直接实现迭代器协议)
2 print(laomuji)#生成器
3 print(laomuji.__next__())#运行结果:鸡蛋0
4 print(laomuji.__next__())#运行结果:鸡蛋1
5 print(laomuji.__next__())#运行结果:鸡蛋2
6 print(laomuji.__next__())#运行结果:鸡蛋3
7 print(next(laomuji))# 生成器只能遍历一次。否则报错。运行结果:鸡蛋4【小于等于鸡蛋9 大于则报错 有界限 大于则StopIteration】

 

总结:

  1.把列表解析的[]换成()则为生成器表达式

  2.列表解析与生成器表达式都为便利的编程方式,但是生成器相对更节省内存【一个一个取值  next()】

  3.python使用迭代器协议 使for循环更通畅,而且大部分内置函数也使用迭代器协议 map() sum() max() min() reduce() filter()

 注:参考https://www.cnblogs.com/linhaifeng/以及老师教学视频

posted @ 2018-06-06 00:14  容颜-gl  阅读(165)  评论(0编辑  收藏  举报