zoukankan      html  css  js  c++  java
  • python迭代器,生成器,列表生成式

    列表生成式

    列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。

    例如:

    >>> [x * x for x in range(1, 11)]
    [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
    

    生成器

    1.定义

    一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator),如果函数中包含yield语法,那这个函数就会变成生成器

    2.作用

    这个yield的主要效果呢,就是可以使函数中断,并保存中断状态,中断后,代码可以继续往下执行,过一段时间还可以再重新调用这个函数,从上次yield的下一句开始执行。

    另外,还可通过yield实现在单线程的情况下实现并发运算的效果

    例如1 :保存中断状态

    def cash_out(amount):
        while amount > 0:
            amount -= 1
            yield 1
        return "done"
    
    
    ATM = cash_out(5)
    try:
        print("取到钱 %s 万" % ATM.__next__())
        print("花掉花掉!")	
        print("取到钱 %s 万" % ATM.__next__())
        print("取到钱 %s 万" % ATM.__next__())
        print("花掉花掉!")
        print("取到钱 %s 万" % ATM.__next__())
        print("取到钱 %s 万" % ATM.__next__())
        print("取到钱 %s 万" % ATM.__next__())  # 到这时钱就取没了,再取就报错了
        print("取到钱 %s 万" % ATM.__next__())
    except StopIteration as e:
        print("%s" %e.value)
    #输出结果
    取到钱 1 万
    花掉花掉!
    取到钱 1 万
    取到钱 1 万
    花掉花掉!
    取到钱 1 万
    取到钱 1 万
    done
    
    

    例如2:单线程进行并发运算

    import time
    
    
    def consumer(name):
        print("%s 准备吃包子啦!" % name)
        while True:
            baozi = yield
    
            print("包子[%s]来了,被[%s]吃了!" % (baozi, name))
            
    def producer(name):
        c = consumer('A')
        c2 = consumer('B')
        c.__next__()
        c2.__next__()
        print("老子开始准备做包子啦!")
        for i in range(10):
            time.sleep(1)
            print("做了2个包子!")
            c.send(i)
            c2.send(i)
            
    producer("alex")
    

    3.返回值

    yield是生成器返回值

    return返回值是StopIterator错误抛出的值

    迭代器

    1.特点

    1. 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
    2. 不能随机访问集合中的某个值 ,只能从头到尾依次访问
    3. 访问到一半时不能往回退
    4. 便于循环比较大的数据集合,节省内存
    >>> a = iter([1,2,3,4,5])
    >>> a
    <list_iterator object at 0x101402630>
    >>> 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
    

    2.常见的迭代器

    py3

    #range使用了迭代器,每次需要获取才调用函数
    >>> range(10)
    range(0, 10)
    #文件读取的时候,read()和readlines()将所有内容都读取到列表,会占用大量内存
    #使用迭代器,一行行的读和操作,性能更优
    f = open("1.txt")
    for i in f:
          print(i)
    

    py2

    >>> range(10)
    [0,1,2,3,4,5,6,7,8,9]
    
    >>> xrange(10)
    range(0, 10)
    

    3.可迭代对象

    一类是集合数据类型,如listtupledictsetstr等;

    一类是generator,包括生成器和带yield的generator function。

    这些可以直接作用于for循环的对象统称为可迭代对象:Iterable

    >>> from collections import Iterable
    >>> isinstance([], Iterable)
    True
    >>> isinstance({}, Iterable)
    True
    >>> isinstance('abc', Iterable)
    True
    >>> isinstance((x for x in range(10)), Iterable)
    True
    >>> isinstance(100, Iterable)
    False
    

    为什么listdictstr等数据类型不是Iterator

    这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

    Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

    listdictstrIterable变成Iterator可以使用iter()函数:

    #list dict string不是迭代器
    >>> from collections import Iterator
    >>> isinstance((x for x in range(10)), Iterator)
    True
    >>> isinstance([], Iterator)
    False
    >>> isinstance({}, Iterator)
    False
    >>> isinstance('abc', Iterator)
    False
    
    #list dict string可以转换为迭代器
    >>> isinstance(iter([]), Iterator)
    True
    >>> isinstance(iter('abc'), Iterator)
    True
    
  • 相关阅读:
    poj 1789 每个字符串不同的字母数代表两个结点间的权值 (MST)
    poj 1251 poj 1258 hdu 1863 poj 1287 poj 2421 hdu 1233 最小生成树模板题
    poj 1631 最多能有多少条不交叉的线 最大非降子序列 (LIS)
    hdu 5256 最少修改多少个数 能使原数列严格递增 (LIS)
    hdu 1025 上面n个点与下面n个点对应连线 求最多能连有多少条不相交的线 (LIS)
    Gym 100512F Funny Game (博弈+数论)
    UVa 12714 Two Points Revisited (水题,计算几何)
    UVa 12717 Fiasco (BFS模拟)
    UVa 12718 Dromicpalin Substrings (暴力)
    UVa 12716 && UVaLive 6657 GCD XOR (数论)
  • 原文地址:https://www.cnblogs.com/akiz/p/11144306.html
Copyright © 2011-2022 走看看