什么是生成器?Python生成器如何使用?

  生成器算得上是Python语言中最吸引人的特性之一,生成器其实是一种特殊的迭代器,不过这种迭代器更加优雅。它不需要再像上面一样在类中定义__iter__() 和__next__() 方法了,只需要在函数中声明一个 yiled 关键字。 所以生成器是一种特殊的迭代器(反之不成立),因此任何生成器也是以一种懒加载的模式生成值。用生成器来实现斐波那契数列的例子是:

  def fib(max):

  n, a, b = 0, 0, 1

  while n < max:

  yield b

  a, b = b, a + b

  n = n + 1

  for i in fib(10):

  print(i)

  (1)生成器对象

  简单说,生成器就是使用了yield关键字的函数:

  def countdown(n):

  print('countdown start')

  while n > 0:

  yield n

  n -= 1

  print('Done!')

  print(countdown) #

  gen = countdown(5)

  print(gen) #

  # 生成器对象也是迭代器对象,一定拥有iter和next,由yield关键字在函数调用时封装好的,不用再自己定义

  # print(gen.__iter__())

  # print(gen.__next__())

  # print(gen.__next__())

  # print(gen.__next__())

  for i in gen:

  print(i)

  解析:生成器函数调用时只会返回一个生成器对象。只有当生成器对象调用__next__方法时才会触发函数体代码执行,直到遇到关键字yield停止,将yield后的值作为返回值返回,所以,yield类似于return的功能,但不同于return的是,return返回,函数结束;而yield将函数的状态挂起,等待生成器对象再次调用__next__方法时,函数从挂起的位置后的第一条语句继续运行直到再遇见yield并返回其后的值;如果不断调用__next__方法,最后一次进入函数体,待执行代码不再有yield此时报出迭代异常的错误。

  另外,对比迭代器,生成器对象多几个方法:

  (1)一个内置的close方法用来关闭自己

  (2)一个内置的send方法,进入生成器,类似于next,但是多一个传值给yield变量的功能。

  yield的功能总结:

  (1)封装iter和next方法 (2)执行函数时遇到yield返回其后的值,不同于return,yiled可以返回多次值 (3)挂起函数的状态,等待下一次调用next方法时找到对应的暂停位置继续执行。

  生成器表达式

  创建一个生成器对象有两种方式,一是通过在函数中创建yield关键字来实现。另一种就是生成器表达式,这是一种类似于数据类型中学过的列表生成式的语法格式,只是将[]换成(),即:

  (expression for item in iterable if condition)

  不同于列表生成式最后返回一个列表结果,生成器表达式顾名思义会返回一个生成器对象,比如:

  >>> [x*x for x in range(4)] # 列表推导式

  [0, 1, 4, 9]

  >>> gen=(x*x for x in range(4))

  >>> gen

  at 0x101be0ba0>

  当需要用到其中的值时,再通过调用next方法或者for循环将值一个个地计算出来:

  >>> next(gen)

  0

  >>> next(gen)

  1

  >>> next(gen)

  4

  >>> next(gen)

  9

  >>> next(gen)

  Traceback (most recent call last):

  File "", line 1, in

  StopIteration

  #------------for 循环------------------

  >>> gen=(x*x for x in range(4))

  >>> for i in gen:

  ... print(i)

  ...

  0

  1

  4

  9

  可迭代对象、迭代器、生成器关系

  面试题

  def add(s, x):

  return s + x

  def gen():

  for i in range(4):

  yield i

  base = gen()

  for n in [1, 10]:

  base = (add(i, n) for i in base)

  print(list(base))

猜你喜欢

转载自blog.csdn.net/oldboyedu1/article/details/133344929