zoukankan      html  css  js  c++  java
  • 迭代器、可迭代对象、生成器

     

    迭代器与可迭代对象

    1、定义:

    可迭代对象:大部分容器如 list,truples,str,sets是可迭代对象,但是他们不是迭代器。可迭代对象实现了__iter__方法,返回一个迭代器,或者使用iter(“可迭代对象”)返回一个迭代器。

    迭代器:迭代器提供了一种不依赖索引取值的方式,这样可以遍历没有索引的可迭代对象,比如字典、集合、文件等等,加载这一个元素至内存中随后释放,相比之下更节省内存,但是我们没有办法获取迭代器的长度,而且只能往后依次取值。遍历的方法使用next(“迭代器”)

    2、代码示例

    d={'a':1,'b':2,'c':3}
    s = d.__iter__()  #s是一个迭代器

    p = iter(“可迭代对象”)  #p是一个迭代器

    #遍历迭代器

    next(p)

    next(p)

    3、for循环

    在for循环中,Python将自动调用工厂函数iter()获得迭代器,自动调用next()获取元素,还完成了检查StopIteration异常的工作。如下

    a = (1, 2, 3, 4)

    for key in a:

        print key

    首先python对关键字in后的对象调用iter函数迭代器,然后调用迭代器的next方法获得元素,直到抛出StopIteration异常。

    4、自定义一个迭代器:

    class Fibs:

        def __init__(self):   #初始化

            self.a = 0

            self.b = 1

           

        def __next__(self):    #获取下一个条目

            self.a, self.b = self.b, self.a + self.b

            return self.a

       

        def __iter__(self):    #返回迭代器

            return self

    fibs = Fibs()    #产生一个对象

    for f in fibs:    #迭代

        if f > 5:

            break

    print(f)

    >>>8

    next(fibs)

    >>>13

    next(fibs)

    >>>21

    生成器
    1)创建生成器

    在一个一般函数中使用yield关键字,可以实现一个最简单的生成器,此时这个函数变成一个生成器函数。

    yield与return返回相同的值,区别在于return返回后,函数状态终止,而yield会保存当前函数的执行状态,在返回后,函数又回到之前保存的状态继续执行。

    2)为何使用生成器

    内存使用更加高效。比如列表是在建立的时候就分配所有的内存空间,而生成器仅仅是需要的时候才会产生。如果我们要读取并使用的内容远远超过内存,但是需要对所有的流中的内容进行处理,那么生成器是一个很好的选择。

    3)生成器函数的特点

    ü  生成器函数包含一个或者多个yield

    ü  当调用生成器函数时,函数将返回一个对象,但是不会立刻向下执行

    ü  生成器中__iter__()和__next__()方法等是自动实现的,所以我们可以通过next()方法对对象进行迭代

    ü  一旦函数被yield,函数会暂停,控制权返回调用者

    ü  局部变量和它们的状态会被保存,直到下一次调用

    ü  函数终止的时候,StopIteraion会被自动抛出

    4)生成器函数构造示例

    l  构造循环生成器

    逆序yield出对象的元素

    def a(my_str):

        length=len(my_str)

        for i in range(length-1,-1,-1):

            yield my_str[i]

    for char in a("hello"):

        print(char)

    l  生成器表达式

    a=(x for x in range(10))

    b=[x for x in range(10)]

    # 这是错误的,因为生成器不能直接给出长度

    # print("length a:",len(a))

    # 输出列表的长度

    print("length b:",len(b))

    b=iter(b)

    # 二者输出等价,不过b是在运行时开辟内存,而a是直接开辟内存

    print(next(a))

    print(next(b)) 

  • 相关阅读:
    梦断代码读书笔记2
    梦断代码读书笔记1
    几篇有用的博客链接
    关于我的Androidstudio的再生
    项目下app目录的具体说明
    关于Android studio的项目界面各部分的认识
    1088 最长回文子串 分类: 51nod 2015-07-20 22:09 8人阅读 评
    1083 矩阵取数问题 分类: 51nod 2015-07-20 22:05 9人阅读 评
    1087 1 10 100 1000 分类: 51nod 2015-07-18 21:59 6人
    51nod 1091 线段的重叠 分类: 51nod 2015-07-18 21:49 7人阅读
  • 原文地址:https://www.cnblogs.com/yongfuxue/p/10036768.html
Copyright © 2011-2022 走看看