• python3.x 基础四:生成器与迭代器


    1.预先存值到内存,调用之前已经占用了内存,不管用与不用,都占用内存

    >>> a=[1,2,3,4,5]
    >>> type(a)
    <class 'list'>
    >>> len(a)
    5
    >>> a = [ i for i in range(1,6)] #列表生成式,这里的i可以是一个函数
    >>> type(a)
    <class 'list'>
    >>> len(a)
    5
    >>> a
    [1, 2, 3, 4, 5]
    
    >>> a=[]
    >>> for i in range(10):
    ...     a.append(i)
    ...
    >>> a
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    2.generateor  一边循环一边计算的机制,节省空间,只有在调用的时候才会生成对应的数据,可以用next访问

    将列表生成式的中括号改成小括号,就变成生成器了

    >>> [ i for i in range(1,6)]
    [1, 2, 3, 4, 5]
    >>> (i for i in range(1,6))
    <generator object <genexpr> at 0x7f8747a69678>
    >>> a=(i for i in range(1,6))
    >>> type(a)
    <class 'generator'>
    >>> 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

    3.斐波那契

    def fib(max):
        n,a,b=0,0,1
        while n<max:
            print(b)
            a,b=b,a+b
            n=n+1
        return 'done'
    fib(10)

    4.将上面的print(b)改成生成式关键字 yield,就是生成器了

    def fib(max):
        n,a,b=0,0,1
        while n<max:
            yield b
            a,b=b,a+b
            n=n+1
        return 'done'
    gen=fib(10)
    print(type(gen))

    5.每次调用生成器的时候,遇到yield则返回本次值,然后跳出生成器,可执行其他指令,在下一次调用生成器的时候,将从上次结束的地方开始运行,直到yield跳出

    def fib(max):
        n,a,b=0,0,1
        while n<max:
            yield b
            a,b=b,a+b
            n=n+1
        return 'done111'
    gen=fib(5)
    print(type(gen))
    print(next(gen))
    print('小明滚进来')
    print(next(gen))
    print('小明滚出去')
    print(next(gen))
    print('小明滚进来')
    print(next(gen))
    print('小明滚出去')
    print(next(gen))
    输出结果:
    <class 'generator'>
    1
    小明滚进来
    1
    小明滚出去
    2
    小明滚进来
    3
    小明滚出去
    5

    6.处理异常try:处理内容 except:内容异常处理

    def fib(max):
        n,a,b=0,0,1
        while n<max:
            yield b
            a,b=b,a+b
            n=n+1
        return 'done111'
    gen=fib(5)
    print(type(gen))
    while True:
        try:
            val=next(gen)
            print('fib value is',val)
        except StopIteration as e:
            print(e.value)
            break
    <class 'generator'>
    fib value is 1
    fib value is 1
    fib value is 2
    fib value is 3
    fib value is 5
    done111

    7.生产者与消费者

    •  g.__next__遇到yield返回,下一次从yield开始,但是不会赋值
    • g.send()遇到yield唤醒迭代器,赋值
    • 进程-线程-携程,epoll异步IO原理
    • epollLinux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。另一点原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了
    #/usr/bin/env python
    #-*- coding: utf-8 -*-
    #Author:jenvid.yang
    import time
    def consumer(name):
        print('%s is ready to have baozi!' %(name))
        while True:
            baozi = yield
            print('baozi %s is coming,baozi was ate by %s' %(baozi,name))
    c=consumer('alex')
    # c.__next__()
    # b1='baozi001'
    # c.send(b1)
    def producer():
        c1=consumer('oldboy')
        c2=consumer('alex')
        c1.__next__()
        c2.__next__()
        print('i am going to make baozi!')
        for i in ['韭菜馅','猪肉馅','白菜陷','玉米馅','萝卜馅']:
            time.sleep(1)
            print('finish 2 baozi')
            c1.send(i)
            c2.send(i)
    producer()

    8.迭代器

    • 列表/元组/字典/集合/字符串/生成器,可以用于for循环的对象统称为可迭代对象:Iterable
    • isinstance(),判断一个一个对象是否是Iterable对象
    • >>> from collections import Iterable
      >>> isinstance([],Iterable)
      True
      >>> isinstance('123',Iterable)
      True
      >>> isinstance({},Iterable)
      True
      >>> isinstance((),Iterable)
      True
    • 能用next()函数调用并返回下一个值的对象成为迭代器,Iterator
    • >>> from collections import Iterator
      >>> isinstance([],Iterator)
      False
      >>> isinstance('123',Iterator)
      False
      >>> isinstance((),Iterator)
      False
      >>> isinstance((i for i in range(2)),Iterator)
      True
    • 生成器是迭代器Iterator,但是Iterable不一定是Iterator,用iter()函数可以将迭代类型转成迭代器
    • >>> isinstance('123',Iterator)
      False
      >>> isinstance(iter('123'),Iterator)
      True
    • 迭代:
      • 迭代器不能预先知道循环的长度
      • 只能通过next()取下一个
      • 最后结果抛出StopIterator错误
      • 可for循环取值的对象是可迭代类型Iterable
      • 可next()取值的对象是迭代器Iterator
     
  • 相关阅读:
    笔记-1、线程基础、线程之间的共享和协作
    token的作用及实现原理
    mybatis+oracle如何批量执行多条update
    java程序员应该熟悉的20个有用的库(转)
    js-textarea文本换行符处理,Java后端以及js前端如何处理
    Spket,eclipse下安装Spket插件,格式化js
    关于equals变量 放在前后的问题
    @Autowired和@Qualifier共用出现提示信息Cannot find bean with qualifier XXXXX
    DOM树简单理解学习
    web.xml 中的listener、 filter、servlet 加载顺序及其详解
  • 原文地址:https://www.cnblogs.com/jenvid/p/7887435.html
Copyright © 2020-2023  润新知