新手入门 | 理解Python中的yield

没有用过的东西,没有深刻理解的东西很难保证自己会,而且一旦被人问起就支支吾吾不知从何说起。这是很多新手学习Python过程中会遇到的问题(当然包括本菜鸟)。本文主要介绍一下python中的生成器和yield关键词。

首先需要说明一下python中的迭代器(iterator)与生成器(constructor)。

一、迭代器

python中可以直接作用于for循环的对象,比如:列表、元祖、字典、集合、字符串等统称为可迭代对象。迭代器是一个实现了迭代器协议的对象,其可以调用next()方法得到下一个结果,在结果末尾调用会产生Stopiteration。此类对象可以使用for 或其他遍历工具进行迭代。最常见的range()就是一个迭代器,好处是每次只从对象中读取一条数据,不会造成内存的过大开销。可以使用isinstance()判断一个对象是否是Iterator对象。

二、生成器

生成器是与迭代器协议相关的,而且生成器都是迭代器。它是python中一种一边循环一边计算的机制,可以节省大量空间。

创建生成器有两种方法,一种是类似列表生成式的,只需要将[]改为()即可。另外就是使用yield关键词,我们主要说一下第二种方法。

举个简单的例子,打印斐波拉契数列。正常写法如下:

def fib(num):
    n, a, b = 0, 0, 1
    while n < num:
        print(b)
        a, b = b, a + b
        n += 1
    return 'done!'

我们只需要简单的将print改为yield,就将原函数变成了生成器函数。

def fib(num):
    n, a, b = 0, 0, 1
    while n < num:
        yield b
        a, b = b, a + b
        n += 1
    return 'done!'

此时我们得到的函数是一个生成器,可以调用next方法得到结果。一般我们使用for循环对其进行遍历。生成器在执行过程中,遇到yield就中断,下次又继续执行。


小练习

杨辉三角定义如下:

         1
        / \
       1   1
      / \ / \
     1   2   1
    / \ / \ / \
   1   3   3   1
  / \ / \ / \ / \
 1   4   6   4   1
/ \ / \ / \ / \ / \
1  5  10  10   5   1

把每一行看做一个list,试写一个generator,不断输出下一行的list

def triangles():
    res = [1]
    while True:
        yield res
        res = [1] + [t[i]+t[i+1] for i in range(len(res)-1)] + [1]

猜你喜欢

转载自blog.csdn.net/wyisfish/article/details/81054098
今日推荐