pythonyield与return
① python中yield和return究竟有什么区别,怎么用
常看到别人使用或讨论yield语法,能搜到的中文解释却不多,今天决心搞定yield,把暂时的理解贴到这里.
搞定yield之前: 叠代器(iterator)
发现yield: 生成器(constructor)
使用yield: 递归调用
1. iterator
叠代器最简单例子应该是数组下标了,且看下面的c++代码:
int array[10];
for ( int i = 0; i < 10; i++ )
printf("%d ", array[i]);
叠代器工作在一个容器里(array[10]),它按一定顺序(i++)从容器里取出值(array[i])并进行操作(printf("%d ", array[i])。
上面的代码翻译成python:
array = [i for i in range(10)]
for i in array:
print i,
for i in array干了什么(别乱想)?首先,array作为一个list是个容器,其次list这个内建类型有默认的next行为,python发现这些之后采 取的秘密的没被各位看到的动作是:拿出array这丫容器的叠代器,从里面next一下把值给i供for循环主体处置,for把这个值print了。
现在的问题是数据可以做容器叠代,代码可以吗?
怎么不行,碗碟可以用来放菜,wk们不就联想出用nt盛吗,当然我们的yield不会那么yellow + bt
2. constructor
怎么把函数变成constructor? 在函数体里有yield就行了!
def gen():
print 'enter'
yield 1
print 'next'
yield 2
print 'next again'
for i in gen():
print i
各位!python看到gen函数里出现yield,知道可以用next了,问题是怎么对代码这个容器玩next?
从容器里拿到iterator的时候它还什么也不是,处在容器入口处,对于数组来说就是下标为-1的地方,对于函数来说就是函数入口嘛事没干,但是万事俱备就欠next。
开始for i in g,next让itreator爬行到yield语句存在的地方并返回值,
再次next就再爬到下一个yield语句存在的地方并返回值,依次这样直到函数返回(容器尽头)。
您一定看出来上面代码的输出是:
enter
1
next
2
next again
如果没看出来请不要往下看了免得反被yield搞定。
3. 使用yield
yield的代码叠代能力不但能打断函数执行还能记下断点处的数据,下次next书接上回,这正是递归函数需要的。
例如中序遍历二叉树:
(应该是David Mertz写的)
def inorder(t):
if t:
for x in inorder(t.left):
yield x
yield t.label
for x in inorder(t.right):
yield x
for n in inorder(tree)
print n
当然yield这种代码next的能力还可以用在其它方面,发现拍案的在贴咯。
② 如何理解Python中的yield用法
Python中的yield用于创建一个可迭代的生成器,它允许函数逐个生成值,而不是一次性返回所有结果。以下是关于yield用法的详细解释:
与return的区别:
- return会一次性返回函数的所有结果,并导致程序终止,局部变量也会被销毁。
- yield则创建一个生成器,通过for循环或next方法逐个生成值,函数在遇到yield时会暂停,并保持局部变量的状态,直到生成器被遍历完。
生成器的概念:
- 生成器是由yield定义的函数,调用它会返回一个生成器对象。
- 当调用生成器对象时,函数会在遇到yield时暂停,保存当前状态。
- 在下一次调用next方法时,函数会从上次暂停的点继续执行,直到遇到下一个yield或函数结束。
生成器的用途:
- 生成器在处理大量数据时特别有用,因为它们可以按需生成数据,避免了一次性加载所有数据导致的内存消耗问题。
- 生成器还可以用于遵循特定逻辑生成数据,如生成斐波那契数列等。
示例:
- 一个简单的生成器函数,使用yield逐个生成数字1, 2, 3。
- 每次调用next方法时,函数会按顺序生成下一个数字,并暂停在当前的yield语句处。
总结:yield是Python中一个强大的特性,它允许函数创建生成器,以逐个生成值的方式处理数据,而不是一次性返回所有结果。这使得生成器在处理大量数据或遵循特定逻辑生成数据时非常高效和内存友好。