python yield是什么意思_python yield有什么用

3e8113f0e53326516bd76e36b1141b13.png

yield是一个常用于python函数定义中的关键字,它的作用是返回一个可以用来迭代(for循环)的生成器,它的应用场景通常为一个需要返回一系列值的,含有循环的函数中。

如果想要彻底搞懂yield关键词的用法,你务必先要搞懂如下词的意思:迭代,可迭代,迭代器,生成器。接下来我将逐一介绍这些词的含义,以及相应的用法。

迭代(iteration)和可迭代(iterable)

迭代是一种操作。很多数据本身就是一种容器(container),它们里面装有各种类型的其他数据,比如列表(list),字典(dict),元组(tuple)等。当我们在实际中使用这些容器的时候,常常需要逐一从里面获取数据,例如说,我们常用for...in...来打印列表中数据,而这种逐个获取数据的过程就叫做迭代。# iteration

a_list = [1, 2, 3]

for i in a_list:

print(i)

可迭代则是对象的一种特性,比如说列表(list)是可迭代的,元组(tuple)是可迭代的,字典(dict)是可迭代的,字符串(string)是可迭代的,file对象也是可以迭代的。因为我们都可以从这些数据类型中逐一获取数据。

迭代器(iterator)

迭代器是一个对象,这种对象每次只能调取一个数据元素。对迭代器不断调用 next() 方法(将迭代起变量放入next()中当参数),则可以依次获取下一个元素;当迭代器中没有元素时,调用 next() 方法会抛出 StopIteration(停止迭代) 异常。迭代器的 __iter__() 方法返回迭代器自身;因此迭代器也是可迭代的。def liebiao():

for x in range(10):

yield x

g = liebiao()

#0

print(next(g))

#1

print(next(g))

#2

print(next(g))

#3

print(next(g))

#4

print(next(g))

#

g.__iter__()

生成器函数(generation function) 和 生成器(generation)

生成器函数是一种特殊的函数,它的函数内部含有yield表达式,调用它会返回一个特殊的迭代器,称生成器。def func():

return 1

def gen():

yield 1

print(type(func)) #

print(type(gen)) #

print(type(func())) #

print(type(gen())) #

yield表达式

如前所述,如果一个函数定义中包含 yield 表达式,那么该函数是一个生成器函数(而非普通函数)。实际上,yield 仅能用于定义生成器函数。

与普通函数不同,生成器函数被调用后,其函数体内的代码并不会立即执行,而是返回一个生成器(generator-iterator)。当返回的生成器调用成员方法时,相应的生成器函数中的代码才会执行。def square():

for x in range(4):

yield x ** 2

square_gen = square()

for x in square_gen:

print(x)

前面说到,for 循环会调用 iter() 函数,获取一个生成器;而后调用 next() 函数,将生成器中的下一个值赋值给 x;再执行循环体。因此,上述 for 循环基本等价于:genitor = square_gen.__iter__()

while True:

x = geniter.next() # Python 3 是 __next__()

print(x)

注意到,square 是一个生成器函数;作为它的返回值,square_gen 已经是一个迭代器;迭代器的 __iter__() 返回它自己。因此 geniter 对应的生成器函数,即是 square。

每次执行到 x = geniter.next() 时,square 函数会从上一次暂停的位置开始,一直执行到下一个 yield 表达式,将 yield 关键字后的表达式列表返回给调用者,并再次暂停。注意,每次从暂停恢复时,生成器函数的内部变量、指令指针、内部求值栈等内容和暂停时完全一致。

换个说法

如果你看不懂生成器函数,也就是带有yield关键字的函数,那么你可以这样去理解:

·在函数开始处,加入 result = list();

·将每个 yield 表达式 yield expr 替换为 result.append(expr);

·在函数末尾处,加入 return result。

也就是说,yield的本质功能还是返回了一个可供迭代的列表。

yield的好处

介绍了这么多定义和用法,那么到底为什么要用yield呢?它有什么样的好处呢?

在很多时候,我们需要逐个去获取容器内的某些数据,而这种仅仅获取部分元素的情况,并不需要我们将容器内所有的元素都取出来。比如说一个容器内现有10000个元素,但我们只需要前5个元素,那么解决办法通常由如下两种:

·获取容器内的所有元素,然后取出前 5 个;

·从头开始,逐个迭代容器内的元素,迭代 5 个元素之后停止。

显而易见,如果容器内的元素数量非常多(比如有 10 ** 8 个),或者容器内的元素体积非常大,那么后一种方案能节省巨大的时间、空间开销。

现在假设,我们有一个函数,其产出(返回值)是一个列表。而若我们知道,调用者对该函数的返回值,只有逐个迭代这一种方式。那么,如果函数生产列表中的每一个元素都需要耗费非常多的时间,或者生成所有元素需要等待很长时间,则使用 yield 把函数变成一个生成器函数,每次只产生一个元素,就能节省很多开销了。

python学习网,免费的在线学习python平台,欢迎关注!

`yield`是Python中的一个关键字,用于定义一个生成器函数。生成器是一种特殊的迭代器,可以通过生成器函数来创建。生成器函数在执行时不会立即返回结果,而是通过`yield`关键字将结果返回给调用者,并暂停函数的执行状态。当下一次调用生成器函数时,函数会从上一次暂停的地方继续执行,直到再次遇到`yield`关键字,然后再次返回结果并暂停执行。这样的过程可以重复执行,直到生成器函数执行完毕或者遇到`return`语句。 使用`yield`可以让我们编写更加简洁高效的代码,因为生成器可以逐个产生结果,而不是一次性产生所有结果。这对于处理大量数据或者需要懒加载的情况非常有用。此外,生成器还可以避免占用过多的内存空间,因为生成器只会在需要时才会产生结果。 下面是一个简单的示例,演示了如何使用`yield`来创建一个生成器函数: ```python def my_generator(): yield 1 yield 2 yield 3 # 创建一个生成器对象 gen = my_generator() # 逐个获取生成器的结果 print(next(gen)) # 输出1 print(next(gen)) # 输出2 print(next(gen)) # 输出3 ``` 在上面的示例中,我们定义了一个`my_generator()`函数,它包含了三个`yield`语句,分别返回1、2、3。当我们调用`my_generator()`函数时,它会返回一个生成器对象,我们可以使用`next()`函数来逐个获取生成器的结果。每次调用`next()`函数时,生成器函数会从上一次暂停的地方继续执行,然后返回下一个结果,直到所有结果都被返回完毕。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值