zoukankan      html  css  js  c++  java
  • 学习7: 列表生成式,生成器,迭代器,可迭代对象

    1) 列表生成式,即创建列表的方式

    列表生成式,这里是中括号[]

    >>> [x*x for x in range(0,10)]
    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    >>> [x * x for x in range(1, 11) if x % 2 == 0]
    [4, 16, 36, 64, 100]
    >>> [m + n for m in 'ABC' for n in 'XYZ']
    ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
    >>> 

    2) 生成器(Generator)
    生成器有两种方法:第一个是通过生成器表达式来创建,另外一种是通过定义带有yield的函数来实现。

    生成器, 这里是小括号()

    >>> (x*x for x in range(0,10))
    <generator object <genexpr> at 0x0000000000C15240>
    >>> 

    说明:从这个可以看出生成器和列表生成的区别:列表生成式直接返回了表达式的结果列表, 而生成器是一个对象,该对象包含了对表达式结果的计算引用。
    前者如果数据量太大时候会占用很大内存,而生成器保存的只是一个计算对象,不会占用很大内存。

    如果上述算法比较复杂,不好写在一个(),那么可以使用定义一个包含yield的函数来实现,这个就是第二种实现方法。
    如果一个函数定义中包含了yield关键字,这个函数就不再是普通函数,而是一个generator object。
    要想调用这个函数,需要使用next()函数,并且遇到yield语句返回(可以把yield理解为return)。例如:

    def test():
        print "one"
        yield 
        print "two"
        yield 
        print 'three'
        yield
    t=test()
    t.next()
    t.next()

    输出结果为:
    one
    two
    [Finished in 0.2s]

    说明:首先创建生成器对象实例t,然后通过next方法调用函数,每一次执行到yield语句会被终止,并在下次该实例再次执行next方法时候继续执行。所以第一个next方法打印one,第二个next打印two.
    test().next()
    test().next()
    输出结果为:
    one
    one
    [Finished in 0.2s]
    说明:注意必须是同一个实例不断调用next方法,如上这种调用方法达不到想要的效果。

    def test():
        print "one"
        yield 
        print "two"
        return
        print "testing"
        yield 
        print 'three'
        yield
    t= test()
    t.next()
    t.next()

    说明:如果生成器中有return,在执行过程中 return,则直接抛出 StopIteration 终止迭代。

    def readfile(file_name):
        seek_option=0
        while True:
            with open(file_name) as f:
                f.seek(seek_option)
                data = f.readline()
                if data:
                    yield data
                    seek_option = f.tell()
                else:
                    return
    print readfile('README.md')
    file = readfile('README.md')
    for data in file:
        print data
    for data in readfile('README.md'):
        print data

    说明: 上述定义了一个读取文件的生成器。生成器一般可以和for循环配合使用,这样可以迭代生成器元素,而不使用next方法。

    3)迭代器(Iterators)
    任何具有__next__()方法的对象都是迭代器。
    所以生成器是一种特殊的迭代器,任意一个生成器都属于迭代器。

    4)可迭代对象
    可迭代对象可以为任意对象,不一定非得是基本数据结构,只要这个对象可以返回一个iterator。
    可迭代对象通过iter函数可以转化为迭代器,如下例a是一个可迭代对象,而b是一个迭代器。
    实际在for循环的过程中也都是将可迭代对象首先转化成迭代器,然后通过next方法读取元素直到抛出异常。

    >>> a=[1,2,3,4]
    >>> b=iter(a)
    >>> type(a)
    <type 'list'>
    >>> type(b)
    <type 'listiterator'>
    >>> b.next()
    1
    >>> b.next()
    2
    >>> 
  • 相关阅读:
    分布式事务基本概念
    rocketmq源码分析3-consumer消息获取
    Mac下的Eclipse不能记住工作空间问题
    rocketmq源码分析2-broker的消息接收
    rocketmq源码分析1-benchmark学习
    metrics
    slf4j与logback对接是如何将日志写到控制台的
    Spring AOP
    hibernate数据库连接池,常用配置
    动态代理
  • 原文地址:https://www.cnblogs.com/lypy/p/6376957.html
Copyright © 2011-2022 走看看