python生成器


定义生成器

正常定义

 def a():
	yield 0
	yield 1
	yield 2

	
>>> ai=a()
>>> type(ai)
<class 'generator'>

定义函数a,得到了一个类为generator的对象,这个对象就是“生成器”

>>> dir(ai)
['__class__', '__del__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__name__', '__ne__', '__new__', '__next__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'gi_yieldfrom', 'send', 'throw']

这里看到了—iter— 和—next—,虽然函数体中没有显示写出这两,仅写了yield语句,但它就已经成为迭代器了。
迭代器的DNA操作还用说吗!

>>> ai.__next__()
0
>>> ai.__next__()
1
>>> ai.__next__()
2
>>> ai.__next__()
Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    ai.__next__()
StopIteration

刚才定义的函数是a的生成器函数,调用它能过得到生成器对象。

生成器解析

还记得之前学过的列表解析吗~:

>>> [x**2 for x in range(11)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

生成器解析和它类似,只不过吧[]变成了()

>>> a = (x**2 for i in range (10))
>>> a
<generator object <genexpr> at 0x0000000002BD5C78>

reutrn与yield的区别

在生成器函数中,yield语句的作用是返回指定对象。return也是一样的,那么2者有合区别呢?

>>> def r_return(n): 
	print("开始")
	while n>0:
		print("在return之前")
		return n
		n-=1               # 1
		print("在return之后")

		
>>> r=r_return(3)         #2
开始
在return之前
>>> r
3

函数定义后,执行调用函数(2),函数体内的语句开始执行,遇到return将值返回,并结束函数体内的执行。所以return后面的语句没有执行(1)

我们再试试yield:

>>> def y_yield(n):
	print("开始")
	while n>0:
		print("在yield之前")
		yield n
		n -=1
		print("在yield之后")	
>>> y=y_yield(3)                # 得到生成器对象
>>> y.__next__()                # 运行生成器
开始
在yield之前
3                               # 返回调用位置,生成器挂起
>>> y.__next__()                # 在当前位置执行之前挂起的地方yield之后
在yield之前
2
>>> y.__next__()yield之后
在yield之前
1

>>> y.__next__()              # 报异常了yield之后
Traceback (most recent call last):
  File "<pyshell#31>", line 1, in <module>
    y.__next__()
StopIteration
>>> 

我们在用生成器做一下斐波那契额数列

>>> def fibs():
	prev,curr = 0,1
	while True:       #无限循环拍不怕
		yield prev    # 没事我们有暂停器~
		prev,curr = curr ,prev+curr

		
>>> import itertools
>>> print(list(itertools.islice(fibs(),10)))  
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

生成器和迭代器都可以省内存。

相关推荐
©️2020 CSDN 皮肤主题: 鲸 设计师:meimeiellie 返回首页