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_camedates 被调用时会怎样? 列表是否返回? 单一个元素吗? 是否再次调用? 以后的电话何时停止?


1. 本代码由Jochen Schulz(jrschulz)编写,他为公制空间制作了一个伟大的Python图书馆,与完整的源:模块mspace链接。


当前回答

一个容易理解它是什么的简单例子:产量

def f123():
    for _ in range(4):
        yield 1
        yield 2


for i in f123():
    print (i)

产出是:

1 2 1 2 1 2 1 2

其他回答

和每个答案一样, 收益被用于创建序列生成器。 它用于动态生成某些序列。 例如, 在按行阅读网络文件行时, 您可以使用以下的收益函数 :

def getNextLines():
   while con.isOpen():
       yield con.read()

您可在您的代码中使用以下代码:

for line in getNextLines():
    doSomeThing(line)

执行控制控制

执行控制将会从 GetNextLines () 转到执行时的循环。 因此, 每次引用 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 translator():
    # load all the words in English language and the translation to 'other lang'
    my_words_dict = {'hello': 'hello in other language', 'dog': 'dog in other language'}

    while True:
        word = (yield)
        yield my_words_dict.get(word, 'Unknown word...')

运行中 :

my_words_translator = translator()

next(my_words_translator)
print(my_words_translator.send('dog'))

next(my_words_translator)
print(my_words_translator.send('cat'))

将打印 :

dog in other language
Unknown word...

概括如下:

使用发件人内部发送方法将数据发送回发件人。要允许,使用 a (ield) 。

收益率和返回一样, 它会返回任何您告诉它的东西( 作为生成器 ) 。 区别在于下次您调用生成器时, 执行从最后一次调用开始到收益语句 。 与返回不同的是, 当收益发生时, 堆叠框架不会被清理, 但是控制会被转回调回调用方, 因此下次调用函数时, 它的状态将会恢复 。

在您的代码中,函数获取_child_camedates 的动作就像一个迭代器,这样当您扩展列表时,它会一次在新列表中添加一个元素 。

列表。extendend calls a plerator until it's fulled it's explator until. 如果是您所贴的代码样本, 只需将图普还给列表, 并附加到列表中, 就会更加清楚 。

发电机可以使个别经过处理的物品立即得到处理(不必等待整个收集过程的处理),下面的例子说明了这一点。

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

许多人使用回报而不是生产,但在某些情况下,收益可以更有效和更便于工作。

这里的例子绝对是收成最佳的:

返回( 在函数)

import random

def return_dates():
    dates = [] # With 'return' you need to create a list then return it
    for i in range(5):
        date = random.choice(["1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th", "10th"])
        dates.append(date)
    return dates

产出(在函数)

def yield_dates():
    for i in range(5):
        date = random.choice(["1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th", "10th"])
        yield date # 'yield' makes a generator automatically which works
                   # in a similar way. This is much more efficient.

呼叫功能

dates_list = return_dates()
print(dates_list)
for i in dates_list:
    print(i)

dates_generator = yield_dates()
print(dates_generator)
for i in dates_generator:
    print(i)

两种函数都做同样的事情, 但产量使用三行而不是五行, 并且有一个更少的变量要担心。

这是代码的结果:

您可以看到两个函数都做相同的事情。 唯一的区别是 返回_ dates () 给出了列表, 而 收益_ dates () 给出了生成器 。

真实生活中的范例就是 逐行读取文件行 或者你只是想制造一个发电机