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

    一、迭代器

    >>> a = iter([1,2,3,4,5])   ---翻译:在内存中创建了一个迭代器对象,a是对其的引用
    >>> type(a)
    <type 'listiterator'>
    >>> a
    <listiterator object at 0x7fcab12a6810>
    >>> for i in a:             ---迭代第一次
    ...     print(i)
    ...
    1
    2
    3
    4
    5
    >>> for i in a:           ---只能迭代一次
    ...     print(i)
    ...
    >>>

    二、列表生成式

     生成一个列表

    >>> l = [i for i in range(0,5)]
    >>> l
    [0, 1, 2, 3, 4]

    三、生成器

    1、

    >>> l = (i for i in range(0,5))
    >>> l
    <generator object <genexpr> at 0x7fcab12ebe10>
    >>> for i in l:
    ...     print(i)
    ...
    0
    1
    2
    3
    4
    >>> for i in l:
    ...     print(i)
    ...
    >>> l.next()    
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration        ----到了stopiteration

    2、yield

    >>> def test(i):
    ...     while i<6:
    ...             yield i
    ...             i = i+1
    ...

    >> test                     ----函数对象
    <function test at 0x7fcab12a85f0>
    >>> test()                   ----函数调用,返回生成器对象
    <generator object test at 0x7fcab12ebe10>

    >>> a = test(x)         ---调用函数,函数里代码并没有执行,函数仅仅返回生成器对象
    >>> a
    <generator object test1 at 0x7fcab12ebe10>

    >>> test(x).next()       ----为什么每次调用,都是111,不应该是123吗?是因为每次都是一次重新调用,返回的都是一个新的生成器对象,所以都是1
    1
    >>> test(x).next()
    1

    >>> test(x).next()
    1
    >>> a.next()           ----直接在a的基础上next就大不一样咯!!因为同一个生成器对象
    1
    >>> a.next()
    2
    >>> a.next()
    3
    >>> a.next()
    4
    >>> a.next()
    5
    >>> a.next()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration               -----------停止迭代了,a所引用的这个生成器对象里面每东西了,生成器对象是惰性的,调用他他才会给你返回值。
    >>> for i in a:
    ...     print(i)
    ...
    >>>
    接下来探究yield究竟发生了什么事情--------------------------------------------------------------------------
    >>> b=test(x)         ------创建一个生成器对象b ,此时函数里的代码并没有运转
    >>> for i in b:       ------for第一次做迭代的时候,函数代码开始运转,直到遇到yield,返回第一个值,第二次循环从yield下一个语句开始,直到再一次遇到yield,一直到i=6,跳过while,此时遇不到yield,认为生成器已经空了,返回StopIteration。以后当然也迭代不了 
    ...     print(i)
    ...
    1
    2
    3
    4
    5
    这个是stackoverflow里的问题,值得一看: http://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do-in-python

    这是中文版: http://taizilongxu.gitbooks.io/stackoverflow-about-python/content/1/README.html

    这篇文章深入浅出 https://www.cnblogs.com/deeper/p/7565571.html

    四、简单小结

    迭代器也好,生成器也好,都是惰性的,因此可以节约大量内存空间。举个例子,一亿个元素的列表放在内存就炸了,但是如果是一个生成器对象,我们用的时候做一个循环,取到我们需要的元素,而且在循环的时候,遵循这样一个过程:计算第一个数,然后内存中丢了,再算下一个数,直到最后。这样大大节省了内存空间。当然用完到StopIteration就没了,只能一次迭代。

    迭代器和生成器有什么区别呢?

    1、生成器是特殊的迭代器,生成器一定是迭代器,迭代器不一定是生成器。

    2、生成器很优雅,不需要迭代器中再定义iter,next,一个关键字yield就ok

    3、生成器可以做send,可以做控制。

  • 相关阅读:
    server.Execute 执行子请求时出错
    mybatis逆向工程
    上传及下载github项目
    基于tess4j的图片文字提取
    myeclipse中更改默认jdk版本出错( Target is not a JDK root. System library was not found)
    SSM整合环境搭建demo
    AMD CPU环境下使用android studio,eclipse的Genymotion插件
    Android Studio电脑不支持HAXM的解决办法
    完整使用JDBC访问数据库
    springMVC保存数据到mysql数据库中文乱码问题解决方法
  • 原文地址:https://www.cnblogs.com/mengmengzhang/p/9693193.html
Copyright © 2011-2022 走看看