zoukankan      html  css  js  c++  java
  • Python的学习之旅———迭代器 生成器

    迭代器

    1 什么叫迭代:迭代是一个重复过程,每次重复都是基于上一次的结果来的
    2 为什么要用迭代器?
    l=['a','b','c']
    n=0
    while n < len(l):
    print(l[n])
    n+=1
    - 对于序列类型:字符串,列表,元组,可以使用基于索引的迭代取值方式,而对于没有索引的类型,如字典,
    集合、文件,这种方式不再适用,于是我们必须找出一种能不依赖于索引的取值方式,这就是迭代器

    3 可迭代的对象:只要对象内置有__iter__方法,obj.__iter__
      数字不可迭代
    4 迭代器对象:对象既内置有__iter__方法,又内置有__next__,如文件对象
    注意:可迭代对象不一定是迭代器对象,而迭代器对象一定是可迭代的对象

    # 可迭代的对象
    # 'hello'.__iter__  字符串
    # [1,2].__iter__    列表
    # (1,2).__iter__   元组
    # {'a':1}.__iter__  字典
    # {1,2,3}.__iter__  集合

    1 dic={'a':1,'b':2,'c':3}
    2 iter_dic=dic.__iter__()
    3 print(dic.__iter__() is dic)
    4 False
    5 
    6 print(iter_dic.__iter__() is iter_dic)
    7 True

    可迭代对象执行__inter__方法之后会得到迭代器对象 (迭代器对象有__next__方法)

    可迭代对象 不等于自己的__inter__()

    迭代器对象等于自己 

    可迭代对象 和迭代器对象 __inter__() 之后都会得到迭代器

    for循环的本质

     1 # while True:
     2 #     try:
     3 #         i=next(iter_dic)
     4 #         print(i)
     5 #     except StopIteration:
     6 #         break
     7 #
     8 
     9 # for i in dic: #iter_dic=dic.__iter__()
    10 #     print(i)

    迭代器的优缺点:
    - 优点:
    提供了一种统一的迭代取值方式,该方式不再依赖于索引
    更节省内存

    同一时间内存只有一个值(T级别的文件打开,然后一个next读一个,内存中就一个值)

    - 缺点:
    无法统计长度
    一次性的,只能往后走,不能往前退,无法获取指定位置的值

     生成器---关键字 yield

    定义:只要函数内部出现yield关键字,那么再调用该函数,将不会立即执行函数体代码,会到到一个结果
    该结果就是生成器对象
    生成器本质就是迭代器
    yield 可以制作自己的迭代器
    yield的功能:
    - 为我们提供了一种自定义迭代器的方式
    - 对比return,可以返回多次,挂起函数的运行状态
     1 # 自定义功能,可以生成无穷多个值,因为同一时间在内存中只有一个值
     2 def my_range(start,stop,step=1):
     3     while start < stop:
     4         yield start
     5         start+=step
     6 
     7 
     8 # g=my_range(1,5,2) #1  3
     9 print(next(g))
    10 print(next(g))
    11 print(next(g))
    12 print(next(g))
    13 print(next(g))
    14 
    15 for i in my_range(1,1000000000,step=2):
    16     print(i)
     1 def func():
     2     print('===>first')
     3     yield 1
     4     print('===>second')
     5     yield 2
     6     print('====>third')
     7     yield 3
     8 
     9 
    10 g=func()
    11 print(g)
    12 
    13 生成器本质就是迭代器
    14 print(next(g))
    15 print(next(g))
    16 print(next(func()))
    17 print(next(func()))
    18 
    19 
    20 for i in g:
    21     print(i)

    for循环的本质就是做了while i=next(g)的操作。而yield又将后面的值 返回给了next(g) 如果不打印i(pirnt(i)) 得到的就会是:

    print('===>first')

    print('===>second')

    print('====>third')

    而没有yield的返回值

    yield的表达式形式的应用
    def eater(name):
        food_list=[]
        print('%s 开动啦' %name)
        while True:
            food=yield food_list #food=‘骨头’
            print('%s 开始吃 %s' %(name,food))
            food_list.append(food)
    
    g=eater('大壮')
    
    g.send(None) #next(g)
    print(g.send('骨头'))
    print(g.send('牛肉'))

    #对于表达式形式的yield,在使用时,第一次必须传None,g.send(None)等同于next(g)

    g.send(None)  执行代码    遇见第一个yeild 停留 return第一个yeild 后面的值

    send('骨头')的操作实际上是会涉及两个yeild,

    • 1 先将'骨头'赋值给上一个执行next(g)操作停留的yield 于是有了food=yeild=‘骨头’    这个yeild是执行next(g)后停留yeild_1.
    • 2 然后再进行next(g)的操作(------------就是向下执行代码)。
    • 3 到下一个yield_2后,将yield_2面的值 返回给next(g), 也就是 next(g)(或者说是g.send(骨头))现在已经是['骨头'].

    作用 可以给函数传入多次值。

    g.close()可以关闭传值

    
    
  • 相关阅读:
    【pandas】读取csv并拆分列
    【Python】读写csv、xlsx乱码,一篇文章搞定
    【mac】彻底移出安装包密码
    【finebi】基于波士顿矩阵模型的应用
    【pandas】3种方法搞定,分组排序求topN
    Supervisord远程命令执行漏洞(CVE-2017-11610)复现
    Visual studio + Qt VS Tool 开发环境相关问题汇总
    SQL学习(五) 高级处理
    SQL学习(四)集合运算
    SQL学习(三) 复杂查询
  • 原文地址:https://www.cnblogs.com/surehunter/p/7646647.html
Copyright © 2011-2022 走看看