Python yield,python的yield用法

  Python yield,python的yield用法

  产量?

  一般来说,yield和return关键字差不多,但是工作方式却大不相同。要完全理解yield是如何工作的,首先需要理解什么是生成器。为了理解什么是生成器,我们必须理解什么是iterable。

  首先,本文给出了一种理解包含yield关键字的函数/代码的简便方法。然后讨论可重写和生成器。在此基础上,讨论了收益率的结构。

  理解葵花宝典的产量关键词

  当遇到包含yield的函数的代码时,可以通过以下方式轻松读取该函数:

  在函数的开头插入result=[]。

  用result.append(表达式)替换所有产量表达式

  在函数末尾插入返回结果

  此时,代码就变成了没有收益的普通代码。重读代码可以很容易理解功能。

  对比原代码,理解yield的含义。

  虽然可以这样理解函数的逻辑,但实际上yield的工作方式与它处理列表替换的方式有很大不同。在某些情况下,从内存和运行时的角度来看,使用yield关键字更有效。在某些情况下,即使原始代码工作正常,使用此方法而不是yield也可能导致无限循环。

  可擦除和迭代器

  对于我列表中的ele:

  循环本体

  在Python中,所有可以在for.in .模式中循环的对象都是可迭代的。例如列表、字符串、文件等。或者,在Python中,所有实现__iter(__方法的类实例都是可迭代的。_ _迭代器(_ _方法必须返回迭代器。迭代器是实现next()方法的对象。在一个类中同时实现__iter__和next是合法的。在这种情况下,__ITER___只是返回自我。这在简单的应用中是没有问题的。但是,如果试图同时用两个或更多迭代器循环同一个对象,这种模式就不符合要求。

  这意味着iterable是任何可以通过调用iterator()方法获得iterator的对象。迭代器是用于循环可迭代对象的对象。

  Python上mylist中for ele的工作模式如下。

  你将得到我的列表迭代器。调用ITER(我的名单)。这个方法返回Python3中next))方法实现__next) _)的对象(迭代器)。

  使用这个迭代器一次遍历我的列表中的一个项目。也就是迭代器中的next()方法不断被调用。接下来))将方法的返回值赋给ele,执行循环体语句。如果迭代器中所有元素都循环,next))方法会抛出StopIteration异常,意味着循环结束。

  实际上,Python在执行循环时会在for循环中显式执行这两个3354,或者执行一个包含隐式循环的操作,比如otherlist.extend(mylist)。其中列出了其他列表。

  因此,Python的iterable包括以下内容:

  Python中可以使用for.in. loop的对象:list,dict,string,files。

  实现用户定义的iter()方法的类实例。

  发电机。

  注意Python的for循环并不关心处理的是哪一个。如果处理是一个迭代器,可以通过next()方法一次调用一个元素,那么for循环可以正常工作。例如,使用For循环访问list的元素、dict的键、文件的行等。一个接一个。

  建设者

  其实生成器的功能和迭代器完全一样,只是生成器和迭代器的区别在于,生成器中的元素只能循环一次。这是因为生成器不会将所有元素都存储在内存中,而是动态生成下一个周期的元素。

  这是一个迭代器。

  mylist=[x*xforxinrange(3]) ]

  对于我列表中的ele:打印(ele)。

  0

  一个

  四

  #这是发电机

  mylist=(x*xforxinrange(3))))))))))))))).

  对于我列表中的ele:打印(ele)。

  0

  一个

  四

  如您所见,只需将[]更改为()即可获得生成器。与迭代器不同,对于生成器,for ele in只能调用一次。

  我的列表.因为生成器会先计算0,然后删除这部分;再算1,然后删除这部分,以此类推。也就是说,生成器不会将之前循环过的任何元素的值保存在内存中。

  产量

  yield关键字的使用类似于return,但区别在于yield关键字使函数返回一个生成器对象。请看下面的示例代码。

  def createGenerator():

  产量1

  产量2

  产量3

  myGenerator=createGenerator()

  打印(我的生成器)#(1)

  对于myGenerator中的ele:

  打印(ele) #(2)

  print(myGenerator.next())

  上述代码的三个输出结果是:

  #(1)

  一个

  2

  三

  #(2)

  回溯(最近一次呼叫):

  文件“”中的第12行

  停止迭代

  #(3)

  从输出结果我们可以看到yield关键字返回一个生成器,这个生成器只能循环一次。

  当调用createGenerator()时,实际上它不会在yield语句中返回任何值。这个函数返回的实际上是一个生成器对象。其实功能并没有退出,只是处于暂停状态。当我们使用for循环遍历生成器时,函数将从挂起状态恢复,并继续执行最后执行的yield语句后面的代码。在createGenerator()中,也就是yield语句的下一行,然后将yield中的值返回给for循环。这个过程会一直持续下去,直到最后函数退出(函数退出,或者生成器为空,表示函数连续运行但是找不到yield语句。这可能是因为函数已经执行到底,也可能是因为我们的函数中包含的if/else条件无法持续满足)。此时,生成器抛出StopIteration异常,for循环结束。注意,当for循环第一次调用生成器时,函数将从头执行到第一个yield,并返回语句中的值。

  相反,如果我们将createGenerator()中的yield替换为return,那么只会执行函数中的第一行,函数在返回1时结束。

  在某种程度上,生成器的功能类似于适配器的功能。一方面,它的next()方法使for循环能够逐个获取下一个值。另一方面,它执行函数,直到获得下一个值,然后将函数重置为挂起状态。

  为什么要用发电机?

  通常,我们可以编写不使用生成器但实现完全相同逻辑的代码。一种方法是使用前面的list方法替换yield关键字。但是这种方法并不总是有效的。例如,当我们有一个无限循环时;而且如果列表很大,这种方法的内存利用效率很低。

  另一种方法是实现另一个iterable类,并通过使用该类中的实例成员来记录状态。利用该类中实现的next()方法(Python3中为__next()__)实现逐循环操作。根据逻辑设计的需要,next()中的代码块可能非常复杂,容易出现bug。在这种情况下,使用发电机也可以提供一个干净的解决方案。

  控制发电机元件的消耗

  class Bank(): #让我们创建一个银行,建造自动取款机

  .危机=错误

  .定义创建_自动柜员机(自身):

  .而不是自我危机:

  .收益 100美元

  当一切正常时,自动取款机会给你你想要的钱

  corner _ street _ ATM=HSBC . create _ ATM()

  print(corner_street_atm.next())

  $100

  print(corner_street_atm.next())

  $100

  print([corner _ street _ ATM . next()for cash in range(5)])

  [$100, $100, $100, $100, $100]

  hsbc.crisis=True #危机来了,没钱了!

  print(corner_street_atm.next())

  wall _ street _ ATM=HSBC . create _ ATM()#甚至对新的自动取款机也是如此

  print(华尔街自动柜员机. next())

  问题是,即使在危机过后,自动取款机仍然是空的

  print(corner_street_atm.next())

  brand _ new _ ATM=HSBC . create _ ATM()#建立一个新的,以恢复业务

  对于全新自动柜员机中的现金:

  .打印现金

  $100

  $100

  $100

  $100

  $100

  $100

  $100

  $100

  $100

  .

  当需要控制资源的获取时,这种方法可能是有用的。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: