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 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个元素的清单来说,这不是什么大不了的事,但是如果你想列出500万个元素的清单,那又会怎样?这不仅仅是一个巨大的记忆食用器,在函数被调用的时候,它还要花费很多时间来构建这个功能。
在第二种情况下, 酒吧只给您一台发电机。 发电机是一个可循环的, 意思是您可以在循环中使用它, 等等, 但每个值只能存取一次。 所有值也并非同时存储在记忆中; 生成器的“ 成员” 对象, 上次您称之为“ 成员” 时, 它在循环中。 这样, 如果您使用一个可( 说) 的转号, 计数为500亿, 你不必一次数到500亿, 然后存储500亿的数值来进行计算。
再者,这是一个相当巧妙的例子,如果你真想数到500亿,你可能会使用滑板。 () :
这是发电机中最简单的使用实例。 正如您所说, 它可以用来写高效的变换, 使用产量将东西推到调用堆叠上, 而不是使用某种堆叠变量。 发电机也可以用于专门的树道, 以及各种其它方式 。
许多人使用回报而不是生产,但在某些情况下,收益可以更有效和更便于工作。
这里的例子绝对是收成最佳的:
返回( 在函数)
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 () 给出了生成器 。
真实生活中的范例就是 逐行读取文件行 或者你只是想制造一个发电机
收益率与返回率相似。区别是:
函数输出使函数可循环( 在以下示例中, 质数( n= 1) 函数成为可循环的 )。 它基本上意味着下次调用函数时, 它会从它离开的地方( 以产出表达式的线为后方) 继续 。
def isprime(n):
if n == 1:
return False
for x in range(2, n):
if n % x == 0:
return False
else:
return True
def primes(n = 1):
while(True):
if isprime(n): yield n
n += 1
for n in primes():
if n > 100: break
print(n)
在上述例子中, 如果是inprime( n) 是真实的, 它会返回质号。 在下一个迭代中, 它会从下一行继续
n += 1
收益率和返回一样, 它会返回任何您告诉它的东西( 作为生成器 ) 。 区别在于下次您调用生成器时, 执行从最后一次调用开始到收益语句 。 与返回不同的是, 当收益发生时, 堆叠框架不会被清理, 但是控制会被转回调回调用方, 因此下次调用函数时, 它的状态将会恢复 。
在您的代码中,函数获取_child_camedates 的动作就像一个迭代器,这样当您扩展列表时,它会一次在新列表中添加一个元素 。
列表。extendend calls a plerator until it's fulled it's explator until. 如果是您所贴的代码样本, 只需将图普还给列表, 并附加到列表中, 就会更加清楚 。