zoukankan      html  css  js  c++  java
  • python 基础 4.4 生成式 生成器 迭代器

    一.生成式和生成器
      列表生成式是python受欢迎的语法之一,通过一句简洁的语法就可以对一组元素进行过滤,还可以对得到的元素进行转换处理。
     
    #/usr/bin/python
    #coding=utf-8
    #@Time   :2017/11/2 21:05
    #@Auther :liuzhenchuan
    #@File   :列表生成式和生成器.py
     
    #求1-100里所有偶数的平方
    #列表生成式法
    print [x*x for x in xrange(1,101) if x%2==0]
     
    #定义函数 for遍历方法
    def fun():
        a = []
        for i in xrange(1,101):
            if i%2==0:
                a.append(i*i)
        return a
    print fun()
     
    >>> [4, 16, 36, 64, 100, 144.....10000]
    >>> [4, 16, 36, 64, 100, 144.....10000]
     
     
     
    2.通过列表生成式,我们可以直接创建一个列表。但是,收到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的内存空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间,在python中,这种一遍循环一边计算的机制,称为生成器(generator)。
       要创建一个generator,有很多方法。第一种方法是把一个列表生成式的[]改成(),就创建了一个generator。
     
    示例:
    ##列表生成器
    #1.要创建一个列表生成器,最简单的办法就是把[] 换成()
    lt =(x*x for x in xrange(1,101) if x%2==0)
    print lt
    print type(lt)
     
    ##通过next()方法,查看列表生成器,当next()最后一个时,next就会报错
    print lt.next()
    print lt.next()
    print lt.next()
     
    >>> <generator object <genexpr> at 0x0372F508>
    <type 'generator'>
    4
    16
    36
     
    #通过循环方法读取列表生成器的值
    lt1 = [51,2,3,5,10,18,60]
    for x in lt1:
            print lt1
    >>> [51, 2, 3, 5, 10, 18, 60]
        [51, 2, 3, 5, 10, 18, 60]
     
    #generator保存的是算法,每次调用next(),就统计算出下一个元素的值。知道计算机到最后一个元素为止。
     
    #2 定义generator的另一种方法,如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator
      #yield 的使用
      ##求10以内数的和
    def fib(n):
        i = 0
        sum = 0
        while i < n:
            sum += i
            i += 1
            print sum
        print '和为:%d' % sum
    fib(10)
     
    print '########当我把第一个sum前加yield时'
     
    def fib(n):
        i = 0
        sum = 0
        while i < n:
            sum += i
            i += 1
            yield(sum)
        print '和为:%d' % sum
    fib(10)
    print type(fib(10))
    for i in fib(10):
        print i
     
    >>>
    0
    1
    3
    6
    10
    15
    21
    28
    36
    45
    和为:45
    ########当我把sum前加yield时,print fib 类型就是成了生成器了
    <type 'generator'>
    0
    1
    3
    6
    10
    15
    21
    28
    36
    45
    和为:45
     
       两次程序的结果和都一样,但是有什么不同呢,简而言之,包含yield语句的函数会被特地编程成生成器,当函数被调用时,他们返回一个生成器对象,这个对象支持迭代器接口,每当遇到yield关键字的时候,你可以理解成函数的return语句,yield后面的值,就是返回的值。但是不像一般的函数在return后退出,生成器函数在生成值后悔自动挂起并暂停他们的执行和状态,他的本地变量将保存状态信息,这些信息在函数恢复时将再度有效,下次从yield下面的部分开始执行。
        解释:1 . 以上函数有关键字yield,所以生成的是一个生成器。
                    2. 通过for循环调用生成器,当执行到yield的时候,返回sum的值,sum为0,此时暂停并记录sum的值
                    3. 打印sum的值,然后继续往下执行,此时跳入一个循环while[1<10]
                    4. 直到遇到yield 的时候,返回sum值。
                     5. 反复执行3,4步骤,知道循环结束,最终程序退出。
     
      二者的区别很明显:
           一个直接返回了表达式的结果列表,而另一个是一个对象,该对象包含了对表达式结果的计算引用,通过循环可以直接输出
            生成器不会一次性列出所有的数据,当你用到的时候,在列出来,更加节约内存的使用。
     
     
     
    二.迭代器
    iterable(可迭代对象) 和 iterator(迭代器) 主要区别是:
    1. 凡是可以用for循环的都是iterable(可迭代对象)  ,凡是需要通过next() 函数获得值得可迭代对象都是iterator(迭代器)
      2. 所以生成器可以被next() 函数调用并不断返回下一个值得对象称为迭代器
      3. 可以简单的理解为生成器就是迭代器的可迭代对象
     
    凡是可作用于for 循环的对像都是iterable 类型
     
    凡是可作用于next()函数的对象都是iterator 类型,他们表示一个惰性计算的序列。
     
     
    #生成式:一次生成所有的数据,然后保存在内存当中,适合小量的数据
    #生成器:返回一个可迭代的对象,及'generator'对象,必须通过循环才可以一一 取出所有的结果
    #可迭代对象:可以通过循环调用出来的,就是可迭代对象。 可迭代对象包括: []  () {}  生成式  生成器
    # 迭代器: 可以简单理解为生成器 。必须通过next() 函数调用并不断返回下一个值得对象就是迭代器。
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    Entity Framework中的多个库操作批量提交、事务处理
    Entity Framework with NOLOCK
    在Entity Framework 中执行T-sql语句
    Entity Framework Extended Library (EF扩展类库,支持批量更新、删除、合并多个查询等)
    Visual Studio 2010 更新NuGet Package Manager出错解决办法
    html判断IE版本
    Java基础-学习笔记(七)——this关键字
    Java基础-学习笔记(六)——类的封装性
    Java基础-学习笔记(五)——面向过程和面向对象的区别
    Java基础-学习笔记(四)-流程控制
  • 原文地址:https://www.cnblogs.com/lzcys8868/p/7777830.html
Copyright © 2011-2022 走看看