• Python迭代器和生成器


    一、迭代器

    现在已知的可迭代对象:str list tuple dict set range和文件句柄。

    但是,什么是可迭代对象?可迭代对象的测量方法。

    方法一: dir(被测对象) 如果 他含有__iter__ ,那这个对象就叫做可迭代对象.

    下面字符串S就是可迭代对象:

    s= 'abcdef'
    print('__iter__' in dir(s))
    可迭代对象,iterable 与迭代器有什么关系?可迭代对象可以转换成迭代器(可迭代对象.__iter__())。
    s1 = s.__iter__()
    print(s1) #iterator  遵循迭代器协议
    
     迭代器的取值:(迭代器.__next__())
    #迭代器取值:
    s2 = 'abcd'
    s3 = s2.__iter__()
    print(s3.__next__())   #a
    print(s3.__next__())   #b
    
    只含有__iter__方法的数据是可迭代对象,含有__iter__方法,并且含有__next__方法的数据是迭代器
    #迭代器的判断:有__iter__方法,并且含有__next__方法的数据是迭代器
    l = [1,2,3,4]
    print('__iter__' in dir(l))  #True
    print('__next__' in dir(l))  #False
    liter = l.__iter__()
    print('__next__' in dir(liter))  #True
    print(liter.__next__())     #1
    print(liter.__next__())     #2
    print(liter.__next__())     #3
    print(liter.__next__())     #4
    

     方法二:测量他是可迭代的还是迭代器:

    # 方法二 测试他是迭代器还是可迭代对象
    l = [1,2,3]
    l_iter = l.__iter__()
    from collections import Iterable
    from collections import Iterator
    print(isinstance(l,Iterable))      #True
    print(isinstance(l,Iterator))      #False
    print(isinstance(l_iter,Iterator)) #True
    print(isinstance(l,list))          #True 

     迭代器的意义:

       1)、迭代器节省内存.
       2)、迭代器惰性机制.
       3)、迭代器不能反复,一直向下执行.

     for 循环的内部机制:

        1)、内部含有__iter__方法,他会将可迭代对象先转化成迭代器.
        2)、然后在调用__next__方法.
        3)、for循环有异常处理的方法. 

    #用迭代器来表示for循环的内部机制
    for i in [1,2,3]:
        print(i)
    l = [1,2,3]
    l_iter = l.__iter__()
    while True:
        try:
            print(l_iter.__next__())
        except StopIteration:
            break
    

     二、生成器 

       什么是生成器?

       生成器是一次生成一个值的特殊类型函数。可以将其视为可恢复函数。调用该函数将返回一个可用于生成连续 x 值的生成器【Generator】

       简单的说就是在函数的执行过程中,yield语句会把你需要的值返回给调用生成器的地方,然后退出函数,下一次调用生成器函数的时候

       又从上次中断的地方开始执行,而生成器内的所有变量参 数都会被保存下来供下一次使用。

       生成器的本质就是迭代器,生成器是自己用python代码写的迭代器。

       1)、可以用生成器函数;

       2)、可以用各种推导式构建迭代器;

       3)、可以通过数据转化。

    生成器函数:

    #生成器函数 生成器
    def gener():
        print('aaa')
        yield 222
        print('bbb')
        yield 333
        print('ccc')
    g = gener()    
    print(g)   #<generator object gener at 0x004A2D80>
    print(g.__next__())  #aaa
                         #222
    print(g.__next__())  #bbb
                         #333

    return yield 区别:

    return 返回给调用者值,并结束此函数.

    yiled 返回给调用者值,并将指针停留着当前位置.

    def func():
        for i in range(10):
            yield i
    g_func = func()
    for i in range(3):
        print(g_func.__next__())  #0 1 2 
    for i in range(3):
        print(g_func.__next__())  #3 4 5 
    

     send和next:

       1)、send 具有和next一样的功能;

       2)、send给上一个yiled 整体发送一个值;

       3)、send不能给最后一个yield发送值;

       4)、获取第一个值的时候,不能用send 只能用next。

    def gener():
        yield 222#AAA
        count = yield 333
        print('-------->',count)
        yield 'aaa'#NONE
        yield 'bbb'
    g = gener()
    print(g.__next__())#222
    print(g.send('AAA'))
    print(g.send(None))
    print(g.send('AAAA'))

     打印结果:

    222
    333
    --------> None
    aaa
    bbb
    打印结果
  • 相关阅读:
    把Linq查询返回的var类型的数据 转换为DataTable EF连接查询
    无法更新 EntitySet 因为它有一个 DefiningQuery
    MVC上传文件
    MySql删除表、数据
    LINQ to Entities 不支持 LINQ 表达式节点类型“ArrayIndex”。
    MVC仓储使用join
    MVC仓储执行存储过程报错“未提供该参数”
    Newtonsoft.Json自动升级版本号,导致dll冲突
    MVC中构建Linq条件、排序、Selector字段过滤
    AutoMapper
  • 原文地址:https://www.cnblogs.com/Ming-Hui/p/8423332.html
Copyright © 2020-2023  润新知