• python之路——函数迭代,生成器


    ---恢复内容开始---

    迭代器 生成器

    迭代器:

    1, 什么是迭代器协议

     ① dir(被测对象) 如果它含有 __iter__,那这个对象叫做可迭代对象,遵循可迭代协议。

     ②  可迭代对象:iterable 可以转换 迭代器(如何实现:都像内部定义一个 __iter__()方法)

      迭代器(iterator)遵循迭代器协议

    2, 迭代器

    1,只含有__iter__方法的数据是课迭代的对象

    l = [1,2,3,4]
    print('__iter__' in dir(l))

    2,含有__iter__方法,并且含有__next__方法的数据是迭代器。

    print(dir([1,2].__iter__()))
    

    3, 迭代器的意义:

    ① 迭代器节省内存

    ② 迭代器有惰性机制

    ③ 迭代器不能反复,一直向下执行。

    4, for 循环机制

    for 可以循环有: 字符串,列表,元祖,字典,集合,说明它们都是可以被迭代的。

    在for循环中,就是在内部调用了__next__方法才能取到一个一个的值。

    那接下来我们就用迭代器的next方法来写一个不依赖for的遍历。

    l = [1,2,3,4]
    l_iter = l.__iter__()
    item = l_iter.__next__()
    print(item)
    item = l_iter.__next__()
    print(item)
    item = l_iter.__next__()
    print(item)
    item = l_iter.__next__()
    print(item)
    item = l_iter.__next__()
    print(item)

    这是一段会报错的代码,如果我们一直取next取到迭代器里已经没有元素了,就会抛出一个异常StopIteration,告诉我们,列表中已经没有有效的元素了。

    这个时候,我们就要使用异常处理机制来把这个异常处理掉

    l = [1,2,3,4]
    l_iter = l.__iter__()
    while True:
        try:
            item = l_iter.__next__()
            print(item)
        except StopIteration:
            break

    那现在我们就使用while循环实现了原本for循环做的事情,我们是从谁那儿获取一个一个的值呀?是不是就是l_iter?好了,这个l_iter就是一个迭代器。

    1,内部含有__iter__方法,他会将可迭代对象先转化成迭代器,然后在调用__next__方法。

    2,它有异常处理方法 

    range 它是可迭代对象,不是迭代器

    验证range 是不是迭代器

    print('__next__' in dir(range(12)))  #查看'__next__'是不是在range()方法执行之后内部是否有__next__
    print('__iter__' in dir(range(12)))  #查看'__next__'是不是在range()方法执行之后内部是否有__next__
    
    from collections import Iterable from collections import Iterator
    print(isinstance(range(100000000),Iterable))
    print(isinstance(range(100000000),Iterator)) #验证range执行之后得到的结果不是一个迭代器

    生成器:

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

    2,生成器的特点:

    ①可以用生成器函数写

    ②可以用各种推导式构建迭代器

       

    ③可以通过数据转化

    3,return 和 yield 的区别

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

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

    import time
    def genrator_fun1():
        a = 1
        print('现在定义了a变量')
        yield a
        b = 2
        print('现在又定义了b变量')
        yield b
    
    g1 = genrator_fun1()
    print('g1 : ',g1)       #打印g1可以发现g1就是一个生成器
    print('-'*20)   #我是华丽的分割线
    print(next(g1))
    time.sleep(1)   #sleep一秒看清执行过程
    print(next(g1))

     4, send :

    1,给上一个 yiled 整体发送一个值

    2, send 不能给最后一个 yiled 发送值

    3, 获取第一个值的时候,不能用 send 只能用 next

    def generator():
        print(123)
        content = yield 1
        print('=======',content)
        print(456)
        yield2
    
    g = generator()
    ret = g.__next__()
    print('***',ret)
    ret = g.send('hello')   #send的效果和next一样
    print('***',ret)

     

    ---恢复内容结束---

  • 相关阅读:
    http 301 和 302的区别
    移动端与PHP服务端接口通信流程设计(增强版)
    导出大量数据到excel表
    c#中两种不同的存储过程调用与比较
    sql存储过程几个简单例子
    高级搜索指令
    SEO 百度后台主动推送链接
    C#利用Web Service实现短信发送(转)
    webservice测试实例
    克服演讲紧张的10个技巧
  • 原文地址:https://www.cnblogs.com/lzg-lzg/p/8423897.html
Copyright © 2020-2023  润新知