zoukankan      html  css  js  c++  java
  • 迭代器和生成器

    一、迭代器

      什么是迭代?迭代器又会是什么?要想知道这些,那就让攀少带领你走进迭代器的世界。

      首先解释一下迭代,即更新换代的意思,这个更新换代是基于上一个版本的。那么我们也就知道迭代器的意思了,器,是工具的意思,迭代器就是迭代取值的工具。

      为什么要用迭代器呢?因为他给我们提供了可以不按索引取值的方法。

    l = [1,2,3,4]
    n = 0
    while n<len(l):
        print(l[n])
        n += 1
    

      重复+每次迭代都是基于上一次的结果而来的。

      需要迭代取值的数据类型:字符串、列表、元组、字典、集合

      什么是可迭代对象?只要内置有_iter_方法的都叫可迭代对象

      在基本类型中,是可迭代对象的有:str list tuple dict set  文件对象(执行内置的_iter_之后还是本身,没有任何变化)

    二、迭代器对象

      迭代器对象满足两个条件:1、内置有_iter_方法,2、内置有_next_方法

      迭代器一定是可迭代对象,而可迭代对象不一定是迭代器对象

    l = [1,2,3,4]
    iter_l = l._iter_()        # 生成一个迭代对象
    print(iter_l._next_())    # 迭代器取值,调用_next_     迭代器取值的话,只能往后依次取,不能后退取值
    print(iter_l._next_())
    print(iter_l._next_())
    print(iter_l._next_())
    print(iter_l._next_())      # 如果取完了就会报错
    d = {'name':'jason','password':'123','hobby':'piao'}
    iter_d = d._iter_()                  #   将可迭代对象d转换成迭代器对象
    print(iter_d._next_())             #  迭代器对象的取值,必须用_next_
    print(iter_d._next_())
    print(iter_d._next_())
    print(iter_d._next_())            #如果值取完了,报错StopIteration  

      出现值取完报错的话,我们一般会进行异常处理,程序如下

    while True:
        try:
            print(iter_d.__next__())
        except StopIteration:
            print('老母猪生不动了')
            break

      如果出现这样的话就不会发生迭代现象,看下图程序

    d = {'name':'jason','password':'123','hobby':'泡m'}
    iter_d = d.__iter__()
    print(d.__iter__().__next__())
    print(d.__iter__().__next__())
    

         输出为: 

      为什么会出现这样的情况,原因是我们不停的让可迭代对象转换成迭代器对象,这样的话永远只会让字典中的第一个元素输出。

      迭代取值的优缺点:

      优点:不依赖于索引取值,内存中永远只占一份空间,不会导致内存溢出

      缺点:不能够获取指定的元素,取完之后会报错

    三、了解for循环的本质

      本质:1.将in后面的对象调用_iter_转换成迭代器对象。2.调用_next_取值。3.内部有异常捕获StopIteration,当_next_报这个错的话就会自动结束程序

    四、生成器

      前面说了迭代器,那为什么要用生成器呢?显然,用生成器在逼格上要比迭代器高几个等级,它没有那么多冗长代码了,而且性能上一样的高效。生成器是用户自定义的迭代器,本质就是迭代器。

    def func():
        print('first')
        yield  666
        print('second')
        yield  777
        print('third')
        yield  888
    g = func()
    print(g)        # 生成器初始化:将函数变成迭代器  <generator object func at 0x0000009EB8552CA8>
    print(g._next_())
    print(g._next_())
    

      函数内如果有yield关键字,那么加括号执行函数的时候并不会触发函数体代码的运行,yield后面就是调用迭代器_next_方法能得到的值,yield既可以返回一个值也可以返回多个值,并且多个值是以元组的形式返回。

      yield帮我们提供了一种自定义生成器方式,将函数运行状态暂停住,可以返回值。与return相同的是,都有返回值,并且可以返回多个,不同的是yield可以返回多次值,return返回一次函数就会立即结束,yield还可以接受外部传入的值。

      

      

      

      

      

    生前无需久睡,死后自会长眠,努力解决生活中遇到的各种问题,不畏将来,勇敢面对,加油,你是最胖的,哈哈哈
  • 相关阅读:
    poj 3436 ACM Computer Factory 夜
    poj 1182 食物链 夜
    poj 2299 UltraQuickSort 夜
    E. Printer 夜
    poj 3083 Children of the Candy Corn 夜
    sdut 2500 0\'s 夜
    1776. Anniversary Firework sdut 2507 焰火表演 夜
    删除上传文件中可能包含的空行
    ALV的fieldcat属性
    ALV显示红绿灯(FM&nbsp;ALV&nbsp;和&nbsp;OO&nbsp;ALV两…
  • 原文地址:https://www.cnblogs.com/panshao51km-cn/p/11190317.html
Copyright © 2011-2022 走看看