• 生成器和迭代器


    生成器:

    Python中,一边循环一边计算的机制,称为生成器:generator

    创建生成器方法1

    把一个列表生成式的 [ ] 改成 ( )

    L = [ x*2 for x in range(5)]
    L
    Out: [0, 2, 4, 6, 8]
    
    G = ( x*2 for x in range(5))
    G
    Out: <generator object <genexpr> at 0x7f626c132db0>
    

    访问生成器的元素:
    -调用next(G)
    -使用 for 循环,因为生成器也是可迭代对象

    创建生成器方法2

    通过函数实现

    def fib(nums):
        n = 0
        a,b = 0,1
        while n<nums:
            print(b)
            a,b = b,a+b
            n+=1
        return result
    
    #此函数可以打印出斐波拉契数列,把 print(b) 改为 yield b,就构建了一个生成器
    def fib(nums):
        n = 0
        a,b = 0,1
        while n<nums:
            yield
            a,b = b,a+b
            n+=1
        return result
    

    用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中

    #用异常来捕获返回值
    f = fib(5)
    
    while True:
        try:
            x = next(f)
            print("value:%d"%x)      
        except StopIteration as e:
            print("生成器返回值:%s"%e.value)
        break
    
    value:1
    value:1
    value:2
    value:3
    value:5
    生成器返回值:result
    

    send和next

    def fun():
        i = 0
        while i<5:
            temp = yield i  //返回i的值,并接受一个send()函数的输入,没有的话就是None
            print(temp)
            i+=1
    f = fun()
    调用 f.__next__()  #f.__next__() 或者 next(f)
    
     f.__next__()
    Out: 0
    
     f.__next__()
    None
    Out: 1
    
     f.__next__()
    None
    Out: 2
    
     f.__next__()
    None
    Out: 3
    
     f.__next__()
    None
    Out: 4
    
     f.__next__()
    None
     ---------------------------------------------------------------------------
    StopIteration                             Traceback (most recent call last)
    <ipython-input-17-468f0afdf1b9> in <module>()
    ---->  f.__next__()
    

    执行到yield时,fun函数作用暂时保存,返回i的值;
    temp接收下次f.send("xxx") 发送过来的值,f.next()等价f.send(None)

    生成器的特点:

    节约内存
    迭代到下一次的调用时,所使用的参数都是第一次所保留下的,即是说,在整个所有函数调用的参数都是第一次所调用时保留的,而不是新创建的


    迭代器

    迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

    1. 可迭代对象

    以直接作用于 for 循环的数据类型有以下几种:

    • 集合数据类型,如 list 、 tuple 、 dict 、 set 、 str 等;
    • generator ,包括生成器和带 yield 的generator function

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

    2. 判断是否可以迭代

    可以使用 isinstance() 判断一个对象是否是可迭代对象:

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

    3. 判断是否是迭代器

    可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
    可以使用 isinstance() 判断一个对象是否是 Iterator 对象

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

    4. iter()函数

    生成器都是 Iterator 对象,但 list 、 dict 、 str 虽然是 Iterable ,却不是 Iterator 。
    把 list 、 dict 、 str 等 Iterable 变成 Iterator 可以使用 iter() 函数:

    isinstance(iter([]), Iterator)
    Out: True
    
    isinstance(iter('abc'), Iterator)
    Out: True
    

    总结

    -凡是可作用于 for 循环的对象都是 Iterable 类型;
    -凡是可作用于 next() 函数的对象都是 Iterator 类型
    -集合数据类型如 list 、 dict 、 str 等是 Iterable 但不是 Iterator ,不过可以通过 iter() 函数获得一个 Iterator 对象。

  • 相关阅读:
    iOS 数据持久化--CoreData
    iOS 数据持久化-- FMDB
    iOS数据持久化--数据库
    iOS数据持久化--归档
    iOS数据持久化--用户属性
    python爬坑记录
    Flutter 爬坑记录
    Web开发爬坑记录
    博客 新址: http://zhoushaoting.com/
    微信小程序开发技巧及填坑记录
  • 原文地址:https://www.cnblogs.com/shuai-long/p/9590350.html
Copyright © 2020-2023  润新知