python中的yield与yield from

生成器与迭代器

在Python中,迭代器就是可以用来迭代(比如for循环中的迭代)操作的对象,任何实现了__next__方法的对象都可以称之为迭代器。

class Fib:
    def __init__(self, n) -> None:
        self.prev = 0
        self.cur = 1
        self.n = n
    
    def __next__(self):
        if (self.n > 0):
            value = self.cur
            self.cur = self.cur + self.prev
            self.prev = value
            self.n -= 1
            return value
        else:
            raise StopIteration()
    
    def __iter__(self):
        return self

f = Fib(10)
print(next(f))
print(next(f))
print([i for i in f])

"""
1
1
[2, 3, 5, 8, 13, 21, 34, 55]
"""

虽然写了好几行代码只是生成了一个列表,但迭代器的优势在于:不用将所有可能用到的数据都加载到内存中,而是通过next方法返回特定的元素,也不用保存之前遍历过的元素。在一些特定的场景下,迭代器可以节省大量的内存。

生成器与迭代器的作用相似,但在用法上更加简洁。在python中,使用了yield关键字的函数会成为生成器函数。函数执行到yield语句后会立即返回,这一点和return的行为一样。不同之处在于:下一次调用该函数的时候,会从yield语句后面接着继续执行。

def fib(n):
    prev, curr = 0, 1
    while n > 0:
        n -= 1
        yield curr
        prev, curr = curr, curr + prev

f = fib(10)
print(next(f))
print(next(f))
print([i for i in f])

"""
1
1
[2, 3, 5, 8, 13, 21, 34, 55]
"""

使用yield from 的关键字也会成为生成器,不过它会将自己的部分任务交给另一个生成器完成。

def func(n):
    print('let\'s go')
    yield from fib(n - 1)
    yield 55

def fib(n):
    prev, curr = 0, 1
    while n > 0:
        n -= 1
        yield curr
        prev, curr = curr, curr + prev

print([i for i in func(10)])

"""
let's go
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
"""

注意:使用'yield from'时,控制权会转移到子生成器,并直接从子生成器中获取值,知道子生成器完成迭代。

posted @ 2024-06-21 17:00  何太狼  阅读(48)  评论(0编辑  收藏  举报