python yield

python yield

ref
ref

可迭代对象

当你使用一个列表生成式来建立一个列表的时候,就建立了一个可迭代的对象。
所有你可以使用 for … in … 语法的叫做一个迭代器:列表,字符串,文件,但它们把所有的值都存储到了内存中。

mylist = [x*x for x in range(3)]
for i in mylist :
	print(i)

生成器

生成器是可以迭代的,但是只可以读取它一次 ,因为它并不把所有的值放在内存中,它是实时地生成数据

mygenerator = (x*x for x in range(3))
	for i in mygenerator :
		print(i)

上面代码看起来除了把 [] 换成 () 外没什么不同。但是,你不可以再次使用 for i in mygenerator , 因为生成器只能被迭代一次:先计算出0,然后继续计算1,然后计算4。。。

yield

yield 是一个类似 return 的关键字,只是这个函数返回的是个生成器。

一个带有 yield 的函数就是一个 generator,它和普通函数不同,生成一个 generator 看起来像函数调用,但不会执行任何函数代码,直到对其调用 next()(在 for 循环中会自动调用 next())才开始执行。虽然执行流程仍按函数的流程执行,但每执行到一个 yield 语句就会中断,并返回一个迭代值,下次执行时从 yield 的下一个语句继续执行。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。

def createGenerator() :
	mylist = range(3)
	for i in mylist :
		yield i*i
mygenerator = createGenerator() # create a generator
print(mygenerator) # mygenerator is an object!
# <generator object createGenerator at 0xb7555c34>
for i in mygenerator:
	print(i)

当你调用这个函数的时候,函数内部的代码并不立马执行 ,这个函数只是返回一个生成器对象。
第一次迭代中你的函数会执行,从开始到达 yield 关键字,然后返回 yield 后的值作为第一次迭代的返回值. 然后,每次执行这个函数都会继续执行你在函数内部定义的那个循环的下一次,再返回那个值,直到没有可以返回的。
如果生成器内部没有定义 yield 关键字,那么这个生成器被认为成空的。

def foo():
    print("starting...")
    while True:
        res = yield 4
        print("res:",res)
g = foo()
#此时未打印出任何信息,说明只是生成了generator对象,并未执行函数
print('-'*30)
print('g_1',next(g))
#调用next,开始执行函数,并且到达yield这一步时,返回生成的4
print("*"*20)
print('g_2',next(g))
#res:none,说明是接着上一步开始执行,并且第二次循环到达yield这一步
print("#"*30)
print('g_3',next(g))
# 1、调用包含yield函数时,并不会执行函数,而是产生并返回一个生成器对象
# 2、第一次next取出一个值时,会将函数执行到第一个yield,停止
# 3、后面next时,会从上一个yield开始,接着执行,循环到下一个yield
send与next

send(msg)与next()的区别在于send可以传递参数给yield表达式,这时传递的参数会作为yield表达式的值,而yield的参数是返回给调用者的值。——换句话说,就是send可以强行修改上一个yield表达式值。比如函数中有一个yield赋值,a
= yield 5,第一次迭代到这里会返回5,a还没有赋值。第二次迭代时,使用.send(10),那么,就是强行修改yield 5表达式的值为10,本来是5的,那么a=10

与return区别

return返回的是一个list列表,而yield每次调用只返回一个数值,毫无疑问,使用return空间开销比较大,尤其是操作巨量数据的时候

itertools

itertools包含了很多特殊的迭代方法。

import itertools
horses = [1, 2, 3, 4]
races = itertools.permutations(horses)
print(races)
# <itertools.permutations object at 0xb754f1dc>
print(list(itertools.permutations(horses)))
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值