何为使用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将一个元素转换成一个生成器。一个生成器的行为就像一个函数,直到某东西“当”为“当”为止。发电机停止直到下一个调用,并且从与开始的完全相同的点继续。您可以通过调用所有“当”值的序列,从一个角度获得所有“当”值的序列。list(generator()).

其他回答

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

缩略yieldKeyword 简单收集返回结果。yield类似return +=

yield:

  • 可以通过停止函数从函数返回一个值多次。
  • 可使用from和它一样yield from.
  • 用于返回大数据时,将其分为小部分数据,以防止大量使用内存。

例如,test()可在以下返回'One', 'Two'['Three', 'Four']以一一一一一一一一一一一一一停止test()so so, so, so, so, so, so, so, so, so,test()停止返回共3倍test()总共3次:

def test():
    yield 'One'                  # Stop, return 'One' and resume 
    yield 'Two'                  # Stop, return 'Two' and resume
    yield from ['Three', 'Four'] # Stop and return ['Three', 'Four'] 

下面这三套代码可以调用test()打印和打印'One', 'Two', 'Three''Four':

for x in test():
    print(x)
x = test()
print(next(x))
print(next(x))
print(next(x))
print(next(x))
x = test()
print(x.__next__())
print(x.__next__())
print(x.__next__())
print(x.__next__())

其结果是:

$ python yield_test.py
One
Two
Three
Four

此外,在使用returnyield,没有办法从return:

def test():
    yield 'One' 
    yield 'Two'
    yield from ['Three', 'Four']
    return 'Five' # 'Five' cannot be got

x = test()
print(next(x))
print(next(x))
print(next(x))
print(next(x))
print(next(x)) # Here

因此,在试图获取'Five':

$ python yield_test.py 
One
Two
Three
Four
Traceback (most recent call last):
  File "C:\Users\kai\yield_test.py", line 12, in <module>
    print(next(x))
          ^^^^^^^
StopIteration: Five

对于那些更喜欢最低限度工作实例的人来说,考虑一下这次交互式的Python会议:

>>> def f():
...   yield 1
...   yield 2
...   yield 3
... 
>>> g = f()
>>> for i in g:
...   print(i)
... 
1
2
3
>>> for i in g:
...   print(i)
... 
>>> # Note that this time nothing was printed

简单解答

函数至少包含一个时yield语句,函数自动成为发电机功能。当您调用发电机功能时, python 在发电机功能中执行代码,直到yield发生声明。yield当您再次调用发电机功能时, python 继续从冻结位置执行发电机功能中的代码,直到yield发电机函数执行代码直到发电机功能用完时没有yield语句。

基准基准基准基准基准基准基准

创建列表并返回它 :

def my_range(n):
    my_list = []
    i = 0
    while i < n:
        my_list.append(i)
        i += 1
    return my_list

@profile
def function():
    my_sum = 0
    my_values = my_range(1000000)
    for my_value in my_values:
        my_sum += my_value

function()

结果有:

Total time: 1.07901 s
Timer unit: 1e-06 s

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     9                                           @profile
    10                                           def function():
    11         1          1.1      1.1      0.0      my_sum = 0
    12         1     494875.0 494875.0     45.9      my_values = my_range(1000000)
    13   1000001     262842.1      0.3     24.4      for my_value in my_values:
    14   1000000     321289.8      0.3     29.8          my_sum += my_value



Line #    Mem usage    Increment  Occurences   Line Contents
============================================================
     9   40.168 MiB   40.168 MiB           1   @profile
    10                                         def function():
    11   40.168 MiB    0.000 MiB           1       my_sum = 0
    12   78.914 MiB   38.746 MiB           1       my_values = my_range(1000000)
    13   78.941 MiB    0.012 MiB     1000001       for my_value in my_values:
    14   78.941 MiB    0.016 MiB     1000000           my_sum += my_value

在飞行上生成值 :

def my_range(n):
    i = 0
    while i < n:
        yield i
        i += 1

@profile
def function():
    my_sum = 0
    
    for my_value in my_range(1000000):
        my_sum += my_value

function()

结果有:

Total time: 1.24841 s
Timer unit: 1e-06 s

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     7                                           @profile
     8                                           def function():
     9         1          1.1      1.1      0.0      my_sum = 0
    10
    11   1000001     895617.3      0.9     71.7      for my_value in my_range(1000000):
    12   1000000     352793.7      0.4     28.3          my_sum += my_value



Line #    Mem usage    Increment  Occurences   Line Contents
============================================================
     7   40.168 MiB   40.168 MiB           1   @profile
     8                                         def function():
     9   40.168 MiB    0.000 MiB           1       my_sum = 0
    10
    11   40.203 MiB    0.016 MiB     1000001       for my_value in my_range(1000000):
    12   40.203 MiB    0.020 MiB     1000000           my_sum += my_value

摘要摘要摘要

生成器函数需要稍多一点时间来执行, 而不是返回列表但少用内存的函数 。