何为使用yield
Python 中的关键字?
比如说,我在试着理解这个代码1:
def _get_child_candidates(self, distance, min_dist, max_dist):
if self._leftchild and distance - max_dist < self._median:
yield self._leftchild
if self._rightchild and distance + max_dist >= self._median:
yield self._rightchild
这就是打电话的人:
result, candidates = [], [self]
while candidates:
node = candidates.pop()
distance = node._get_dist(obj)
if distance <= max_dist and distance >= min_dist:
result.extend(node._values)
candidates.extend(node._get_child_candidates(distance, min_dist, max_dist))
return result
当方法_get_child_candidates
是否调用 ? 列表是否返回 ? 单元素 ? 是否又调用 ? 以后的呼叫何时停止 ?
1. 本代码由Jochen Schulz(jrschulz)编写,他为公制空间制作了一个伟大的Python图书馆。模块 m 空间.
所有的答案都是伟大的, 但对于新人来说有点困难。
我猜你已经学会了return
语句。
作为类比,return
和yield
双胞胎。return
意指“返回和停止”,而“真正”意指“返回,但继续”
- 尝试获得 num_ list 列表
return
.
def num_list(n):
for i in range(n):
return i
运行它:
In [5]: num_list(3)
Out[5]: 0
你看,你只得到一个数字 而不是他们的名单。return
永远不允许你快乐地胜利, 仅仅一次执行,然后退出。
- 来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来来
yield
替换return
与yield
:
In [10]: def num_list(n):
...: for i in range(n):
...: yield i
...:
In [11]: num_list(3)
Out[11]: <generator object num_list at 0x10327c990>
In [12]: list(num_list(3))
Out[12]: [0, 1, 2]
现在,你赢得了所有的数字。
与return
运行一次,停止一次,yield
计划运行时间。您可以解释return
计为return one of them
, 和yield
计为return all of them
。这被称为iterable
.
- 再来一步,我们可以改写
yield
声明的语中return
In [15]: def num_list(n):
...: result = []
...: for i in range(n):
...: result.append(i)
...: return result
In [16]: num_list(3)
Out[16]: [0, 1, 2]
这是核心yield
.
列表之间的差别return
输出和对象yield
输出为 :
您将总是从列表对象中获取 [0, 1, 2] 列表对象, 但只能从“ 对象” 中获取它们yield
输出一次。 所以, 它有一个新名称generator
对象显示于Out[11]: <generator object num_list at 0x10327c990>
.
最后,作为格罗克语的比喻:
return
和yield
双胞胎
list
和generator
双胞胎
又一个TRL;DR
列表中的迭代器: next()
返回列表的下一个元素
热机发电机: next()
将计算苍蝇上的下一个元素( 执行代码)
您可以看到生成/生成器作为手动运行控制流量从外部( 如继续循环一步骤) 调用next
无论流量如何复杂。
Note发电机是不无一个普通函数。它会像本地变量( stack) 一样记得以前的状态( stack) 。请参看其他答案或文章以详细解释。生成器只能是曾经变热过一次. 你可以没有yield
,但它不会是那么好, 所以它可以被认为是“非常好”的语言糖。
就像每个答案都暗示的那样yield
用于创建序列生成器。 它用于动态生成某些序列。 例如, 在网络上逐行读取文件行时, 您可以使用yield
函数如下:
def getNextLines():
while con.isOpen():
yield con.read()
您可在您的代码中使用以下代码:
for line in getNextLines():
doSomeThing(line)
执行控制控制
执行控制将从下拉林( GetNextLines) 转到for
当输出被执行时循环。 因此, 每次引用 NextLines () 时, 执行从上次暂停的点开始 。
因此,简言之,一个函数具有以下代码
def simpleYield():
yield "first time"
yield "second time"
yield "third time"
yield "Now some useful value {}".format(12)
for i in simpleYield():
print i
将打印
"first time"
"second time"
"third time"
"Now some useful value 12"
发电机可以使个别经过处理的物品立即得到处理(不必等待整个收集过程的处理),下面的例子说明了这一点。
import time
def get_gen():
for i in range(10):
yield i
time.sleep(1)
def get_list():
ret = []
for i in range(10):
ret.append(i)
time.sleep(1)
return ret
start_time = time.time()
print('get_gen iteration (individual results come immediately)')
for i in get_gen():
print(f'result arrived after: {time.time() - start_time:.0f} seconds')
print()
start_time = time.time()
print('get_list iteration (results come all at once)')
for i in get_list():
print(f'result arrived after: {time.time() - start_time:.0f} seconds')
get_gen iteration (individual results come immediately)
result arrived after: 0 seconds
result arrived after: 1 seconds
result arrived after: 2 seconds
result arrived after: 3 seconds
result arrived after: 4 seconds
result arrived after: 5 seconds
result arrived after: 6 seconds
result arrived after: 7 seconds
result arrived after: 8 seconds
result arrived after: 9 seconds
get_list iteration (results come all at once)
result arrived after: 10 seconds
result arrived after: 10 seconds
result arrived after: 10 seconds
result arrived after: 10 seconds
result arrived after: 10 seconds
result arrived after: 10 seconds
result arrived after: 10 seconds
result arrived after: 10 seconds
result arrived after: 10 seconds
result arrived after: 10 seconds