python 生成器(generator),迭代器(iterator)与yield

python 生成器(generator),迭代器(iterator)与yield

前言

OOAD课程是用python教的,其中涉及到大量的python语法糖,老师也算是手把手教如何写出OO的python,但一个学期没听课只能期末补一补。

概念引入

generator

python是一门很灵活的函数,对于列表的创建什么的都很简单, 考虑这样一种情况,一个列表中有100万个元素,但仅仅只有几个元素是业务需要的,那么大量的内存空间都被浪费了.

如果这个列表里的元素都基于一定规则,如斐波那契数列,那么我们可以采用python内置的生成器(generator)来进行一边循环一边计算.

下面的代码还原了generator的计算逻辑:

def fib(fibonacci):
    n, a, b = 0, 0, 1
    while n < fibonacci:
        print(b)
        a, b = b, a + b
        n = n + 1


fib(6)

yield

如果我们需要将其变为generator,则需要使用yield关键字:

换句话说,带了yield关键字的函数就是generator (注意是可以使用多个yield关键字哒)

def fib(fibonacci):
    n, a, b = 0, 0, 1
    while n < fibonacci:
        yield b
        a, b = b, a + b
        n = n + 1


for n in fib(6):
    print(n)

由此,其通过for循环迭代每个元素并打印,实现了和上面的代码一样的效果.

在每次循环的时候,生成器函数都会在yield处产生一个值,并将其返回给调用者,即for循环。然后在yield处保存内部状态,并挂起中断退出。在下一轮迭代调用时,从yield的地方继续执行,并且沿用上一轮的函数内部变量的状态,直到内部循环过程结束。

除此之外,还有一种叫做生成器表达式:

就是将中括号写成了小括号,两者返回的结果不一致:

image-20210106202530315

Iterator

看Wiki的解释:

在Python中,迭代器是遵循迭代协议的对象。使用iter()从任何序列对象中得到迭代器(如list, tuple, dictionary, set等)。另一种形式的输入迭代器是generator(生成器)。

说回斐波那契数列,作为generator,自然也就是Iterator,python提供了next()函数以备使用.

image-20210106192024708

调用next()函数,直接将fib(6)作为参数传入,返回迭代元素.

可迭代对象

那么什么才是迭代器呢?迭代器和可迭代对象有什么区别?

先去尝试了比较常见的集合:

image-20210106193325001

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

而上文中摘录的Wiki告诉我们,python提供了iter()函数供我们将可迭代对象转换为迭代器:

python也提供了isinstance()判断一个对象是否为某某的实例化对象,于是我们先测试s = [1, 2, 3]是否为可迭代对象:

from collections.abc import Iterable
s = [1, 2, 3]
print(isinstance(s,Iterable)) # print True

image-20210106194851067

使用范例

... 考完试再填坑.

Reference

https://www.liaoxuefeng.com/wiki/1016959663602400/1017323698112640

https://developer.ibm.com/zh/technologies/analytics/tutorials/ba-on-demand-data-python-1/

https://zhuanlan.zhihu.com/p/76831058 (这篇讲得很清晰)

posted @ 2021-01-06 20:35  不周客  阅读(231)  评论(0编辑  收藏  举报