何为使用yieldPython 中的关键字?

比如说,我在试着理解这个代码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 空间.

当前回答

就像每个答案都暗示的那样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"

其他回答

yield简直就像return区别在于,下次你打电话给发电机时,从最后一次呼叫开始执行。yield与返回不同的语句,当生成时, 堆叠框架不会被清理, 但是控件会被转回调用方, 所以下次调用函数时, 它的状态将会恢复 。

对于您的代码,函数get_child_candidates动作就像一个循环器,这样当您扩展列表时,它会一次向新列表添加一个元素。

list.extend在你公布的代码样本中, 只需将图普还给列表, 并附加到列表中, 就会更加清晰 。

就像每个答案都暗示的那样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"

失败给了你一台发电机

def get_odd_numbers(i):
    return range(1, i, 2)
def yield_odd_numbers(i):
    for x in range(1, i, 2):
       yield x
foo = get_odd_numbers(10)
bar = yield_odd_numbers(10)
foo
[1, 3, 5, 7, 9]
bar
<generator object yield_odd_numbers at 0x1029c6f50>
bar.next()
1
bar.next()
3
bar.next()
5

如你所见,第一种情况foo将整个列表同时保留在记忆中。 对于包含 5 个元素的列表来说, 这不是什么大问题, 但如果您想要 5 百万 的列表, 那又会怎样 ? 这不仅仅是一个巨大的记忆食用器, 在函数被调用时, 它还要花费很多时间来构建 。

在第二个案件中,bar发电机是可循环的 也就是说你可以用在for循环等, 但每个值只能存取一次 。 所有值也并非同时存储在记忆中; 生成器对象“ Remember ” 。 上次您称之为循环时, 生成器对象“ remember ” 正在循环中, 这样, 如果您正在使用一个可( 说) 的转号, 计为 500 亿, 那么您不必同时计为 500 亿, 然后存储500 亿 个数字来进行计算 。

再者,这是一个相当巧妙的例子,如果你真想数到500亿,你可能会使用滑板。 () :

这是发电机中最简单的使用实例。 正如您所说, 它可以用来写高效的变换, 使用产量将东西推到调用堆叠上, 而不是使用某种堆叠变量。 发电机也可以用于专门的树道, 以及各种其它方式 。

(我下面的回答只从使用Python发电机的角度,而不是从使用Python发电机的角度,而不是从使用Python发电机的角度来回答发电机机制基本实施,这涉及一些玩弄堆叠和堆积操纵的把戏。 ))

何时yield使用代替return在 python 函数中,该函数被转换为特殊的东西,称为generator function该函数返回generator类型。缩略yield关键字是通知 Python 编译者专门处理此函数的标志。正常函数一旦从中返回某些值, 正常函数就会终止。 但是, 在编译器的帮助下, 生成器函数将会终止 。能够被想象到即,执行环境将恢复,执行将持续到最后一年。直到你明确要求返回,这会引起StopIteration选项(这也是迭代协议的一部分),或达到函数的结尾。我发现很多关于generator但这个1个调自自functional programming perspective是最可消化的。

(现在我想谈一下为什么generatoriterator我希望这能帮助你掌握基本动机和基本动机这一概念以其他语言出现,如C#。 )

据我所知,当我们想要处理一堆数据时, 我们通常先把数据存放在某处,然后一个一个地处理。但是这个是。幼天如果数据量很大, 事先将数据全部储存起来是昂贵的 。而不是储存data为什么不直接储存某种metadata间接,即:the logic how the data is computed.

有两种方法可以包扎这类元数据。

  1. OO 方法,我们包封元数据as a class这就是所谓的iterator执行滚动协议(即__next__(), 和__iter__()这也是人们所普遍看到的方法。电动电机设计图案.
  2. 功能方法,我们包封元数据as a function这就是所谓的generator function但是在兜帽帽下, 返回的人generator object仍为IS-A因为它还执行传动协议 。

无论哪种方式, 都会创建一个迭代器, 即某个可以提供您想要的数据的对象。 OO 处理方式可能有点复杂。 总之, 由您决定使用哪一种 。

还有一个yield用途和含义(自 Python 3.3 以来):

yield from <expr>

发自PEP 380-从属子生成器的语法:

提议对发电机使用语法,将部分操作权下放给另一个发电机,这样可以将含有“当量”的代码部分计入到另一个发电机中。此外,允许次发电机返回一个值,并将价值提供给授权发电机。

新的语法也为当一个发电机再生一个发电机产生的另一个发电机价值时实现最佳化开辟了一些机会。

此外,这笔将引入(自Python 3. 5) :

async def new_coroutine(data):
   ...
   await blocking_action()

避免与常规发电机混淆(今天)yield两者都使用)。