Python 全栈:理解三大器练习

  • 201 直观理解 yield
  • 202 yield与生成器
  • 203 yield 和 send函数
  • 204 yield 使用案例之嵌套 list 的完全展开
  • 205 yield 使用案例之列表分组
  • 206 可迭代协议之 *iter* 方法使用案例
  • 207 迭代器相关方法之 next 函数使用
  • 208 定制一个递减迭代器案例
  • 209 Python 生成枚举对象的方法
  • 210 列表和迭代器区别
  • 211 节省内存的案例
  • 212 拼接迭代器
  • 213 累积迭代器
  • 214 漏斗迭代器
  • 215 drop 迭代器
  • 216 take 迭代器
  • 217 克隆迭代器
  • 218 复制元素
  • 219 笛卡尔积
  • 220 加强版zip
  • 221 自定义装饰器之call_print
  • 222 装饰器本质
  • 223 wraps 装饰器
  • 224 统计程序异常出现次数的迭代器
  • 225 实现一个按照 2*i+1 自增的迭代器

201 直观理解 yield

要想通俗理解 yield,可结合普通函数的返回值关键字 return,yield便是一种特殊的return.

说是特殊的 return,是因为执行遇到 yield 时,立即返回,这是与 return 的相似之处。

不同之处在于:下次进入函数时直接到 yield 的下一个语句,而 return 后再进入函数,还是从函数体的第一行代码开始执行。

yield 的函数是生成器,通常与 next函数 结合用。下次进入函数,意思是使用 next函数 进入到函数体内。

举个例子说明 yield 的基本用法。

下面是被熟知的普通函数 f, f() 就会立即执行函数:

In [1]: def f():
   ...:     print('enter f...')
   ...:     return 'hello'

In [2]: ret = f()
enter g...

In [3]: ret
Out[3]: 'hello'

但是,注意观察下面新定义的函数 f,因为带有 yield,所以是生成器函数 f

def f():
    print('enter f...')
    yield 4
    print('i am next sentence of yield')

执行 f,并未打印任何信息:

g = f()

只得到一个生成器对象 g

再执行 next(g) 时,输出下面信息:

In [18]: next(g)
enter f...
Out[18]: 4

再执行 next(g) 时,输出下面信息:

In [23]: next(g)
i am next sentence of yield
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
 in 
----> 1 next(g)

StopIteration:

输出信息 i am next sentence of yield, 表明它直接进入yield的下一句。

同时,抛出一个异常:StopIteration,意思是已经迭代结束。

202 yield与生成器

函数带有 yield,就是一个生成器,英文 generator,它的重要优点:节省内存

可能有些读者不理解怎么做到节省内存的?下面看一个例子。

首先定义一个函数 myrange:

def myrange(stop):
    start = 0
    while start < stop:
        yield start
        start += 1

使用生成器 myrange:

for i in myrange(10):
    print(i)

返回结果:

0
1
2
3
4
5
6
7
8
9

整个过程空间复杂度都是 O(1),这得益于 yield 关键字,遇到就返回且再进入执行下一句的机制。

以上完整过程,动画演示如下:

你可能感兴趣的:(Python 全栈:理解三大器练习)