zoukankan      html  css  js  c++  java
  • 【python基础】迭代器和生成器函数

    1、迭代器协议:

    1、迭代器协议是指:对象必须提供一个 __next__() 方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代(只能往后走不能往前退)

    2、可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义了一个__iter__()方法)

    3、协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象。

    注意:

    iter.ls__next__()   #__next__()   ---->next()   __next__() 是迭代器内置函数,而next() 是python内置函数,两者效果相同

    字符串、列表、元组、字典、集合等 都不是可迭代对象,但是能够被for循环,

    for循环其实就是先把它们转化为可迭代对象( li.__iter__()或者iter(li) ),然后进行__next__()方法一个个取出

    >>> 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

    >>>for i in range(a):
        print(i)
    >>>1
    >>>2
    >>>3
    >>>4
    >>>5
    #当遇到StopIteration时停止迭代

    2、生成器

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

    li = ['鸡蛋%s'%i for i in range(10)]   #生成器表达式
    print(li)

    在函数中只能有一个return 返回,但是却可以有多个yield 生成器返回

    def func():
        print('1111')
        print('2222')
        yield 1
        print('aaa')
        yield ('bbb')
        yield "success"
        print('ccc')
        yield "enter"
    
    fx = func()
    print(fx.__next__())     # 第一次使用__next__()打印到yield 1 的位置, 1111  2222  1
    print(fx.__next__())     # 第二次使用__next__()打印到yield 'bbb' 的位置, aaa  bbb
    print(fx.__next__())    #success
    print(fx.__next__())    #ccc  enter

     有效利用yield生成器这个工具可以有效地节约系统资源,避免不必要的内存占用

    yield生成器每次生出一个值占用较少的内存,就像餐馆里上餐是做好一个菜上一个菜而不是把全部菜都做好了之后再上菜

    """yield i+1 每次向内存中放入一个值,占用较少的内存"""
    def func1():
        for i in range(100):
            yield i+1
    
    f1 = func1()
    print('来了第%s个人'%(f1.__next__()))    #来了第1个人
    print('来了第%s个人'%(f1.__next__()))    #来了第2个人
    print('来了第%s个人'%(f1.__next__()))    #来了第3个人
    
    """return ret 是将生成的[1,2,3,4...100]数组直接放在内存中,耗费较多内存"""
    def func2():
        ret = []
        for i in range(100):
            ret.append(i+1)
        return ret
    f2 = func2()
    print("来了第%s个人"%(f2[1]))    #来了第2个人
    yield比return占用较少内存

     

     

     

    补充知识点

    三元表达式:

    """三元表达式"""
    name = 'jt'
    res = 'xiong' if name == 'jt' else 'zhang'
    print(res)

    列表解析:

    egg_list = []
    for i in range(10):
        egg_list.append('鸡蛋%s'%i)
    print(egg_list)
    
    """列表解析""" li
    = ['鸡蛋%s'%i for i in range(10)] print(li) #打印出来的结果都是: ['鸡蛋0', '鸡蛋1', '鸡蛋2', '鸡蛋3', '鸡蛋4', '鸡蛋5', '鸡蛋6', '鸡蛋7', '鸡蛋8', '鸡蛋9']

    """列表解析与三元表达式结合"""
    li = ['鸡蛋%s'%i for i in range(10) if i>5]
    print(li)
    #打印出来的结果都是:
    ['鸡蛋6', '鸡蛋7', '鸡蛋8', '鸡蛋9']

    #注意:
    #li = ['鸡蛋%s'%i for i in range(10) if i>5 else i<2]   #没有4元表达式 这种写法错误
  • 相关阅读:
    Apache commons-net用法的一个示例
    Apache commons(Java常用工具包)简介
    MyBatis动态sql之${}和#{}区别
    Spring事务管理
    Spring:源码解读Spring IOC原理
    Spring常用注解总结
    maven常用命令
    Spring事务回滚和异常类
    CSS3--难以想象的滤镜效果
    Composer安装
  • 原文地址:https://www.cnblogs.com/XJT2018/p/10007113.html
Copyright © 2011-2022 走看看