快速提示:了解 Python 中的 Yield 关键字

感谢Shaumik Daityari帮助对本文进行同行评审。

当我们在 Python 中调用一个函数时,该函数通常会开始工作,直到遇到 a returnexception或到达其结尾——之后它将控制权返回给调用者。每当您再次调用该函数时,该过程将从头开始

假设你让一个人跟踪路上的红色汽车。该人将不断收到一个问题,询问他们是否发现了一辆红色汽车,而该人反过来会回答“是”或“否”。如果这个人回答“是”,红色汽车被发现的次数将会增加。

让我们看看如何在 Python 中做到这一点:

import time

def red_cars(answer):
    n = 0
    while True:
        if answer == 'yes':
            n = n + 1
            return n
        else:
            return n

stop = time.time() + 5 * 60
while time.time() < stop:
    answer = raw_input('Did you spot a red car on the road? ("yes" or "no"): ')
    times = red_cars(answer)
    print 'You have spotted ' + str(times) + ' cars so far!'

如果你运行这个程序,你会注意到什么?您是否注意到回答“是”的次数总是上限为1,而当您回答“否”时,0无论之前回答“是”,次数都会增加?

这就是 Python 的yield关键字发挥作用的地方。yield是我们暂时将控制权交给调用者的一种方式,并期望从控制权移交的那一点继续。

在给出上述示例的解决方案之前,让我演示一个非常简单的示例,以更好地说明其yield工作原理。

假设我们有以下简单的 Python 脚本:

def step_by_step():
    return 'step 1'
    return 'step 2'
    return 'step 3'
    
step = step_by_step()
for i in range (3):
    print step

如果运行脚本,您将获得以下输出:

step 1
step 1
step 1

现在,如果我们yield改为使用,如下所示:

def step_by_step():
    yield 'step 1'
    yield 'step 2'
    yield 'step 3'
    
step = step_by_step()
for i in range (3):
    print step.next()

输出如下:


step 1
step 2
step 3

如您所见,我们能够创建一系列值,因为对于每次调用,函数都会从产生值的点继续。这种类型的函数称为生成器。这样的函数创建了一个生成器迭代器,就像每次调用next()我们移动到下一条yield语句的方法一样。

如果我们回到我们的主要示例(红色汽车),可以编写如下来执行所需的任务:

import time

def red_cars(answer = None):
    n = 0
    while True:
        if answer=="yes":
            n = n + 1
            answer = yield n
        else:
            answer = yield n

car_color = red_cars()
car_color.next()

stop = time.time() + 5 * 60
while time.time() < stop:
    answer = raw_input('Did you spot a red car on the road? ("yes" or "no"): ')
    print 'You have spotted ' + str(car_color.send(answer)) + ' cars so far!'

因此,正如我们所看到的,yield当我们有兴趣在函数(生成器)退出的最后一点恢复执行时,以及我们也有兴趣在不同调用之间保持局部变量的值时,这被认为很重要——这与普通函数不同,其中这些值在退出函数时被销毁。

但是,还有其他用途yield。例如,yield如果您有一个返回序列的函数(例如,Excel 工作表中的行)并且您需要迭代序列而不同时将每个值都保存在内存中,则可以使用该函数。也就是节省内存。

yield也可以在使用 iterables 时使用,我们有一个很难在函数之间传递的大列表。例如,Python 在itertools 模块中用于排列和组合的内置函数使用yield.如果对Python有兴趣,想了解更多的Python以及AIoT知识,解决测试问题,以及入门指导,帮你解决学习Python中遇到的困惑,我们这里有技术高手。如果你正在找工作或者刚刚学校出来,又或者已经工作但是经常觉得难点很多,觉得自己Python方面学的不够精想要继续学习的,想转行怕学不会的, 都可以加入我们,可领取最新Python大厂面试资料和Python爬虫、人工智能、学习资料!微信公众号【Python大本营】等你来玩奥~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值