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链接。
发电机可以使个别经过处理的物品立即得到处理(不必等待整个收集过程的处理),下面的例子说明了这一点。
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
这样想吧:
迭代器只是具有下一个( ) 方法的对象的奇特探测术语。 因此, 产生式的函数最终会变成这样 :
原文:
def some_function():
for i in xrange(4):
yield i
for i in some_function():
print i
Python 翻译用上述代码所做的基本上就是:
class it:
def __init__(self):
# Start at -1 so that we get 0 when we add 1 below.
self.count = -1
# The __iter__ method will be called once by the 'for' loop.
# The rest of the magic happens on the object returned by this method.
# In this case it is the object itself.
def __iter__(self):
return self
# The next method will be called repeatedly by the 'for' loop
# until it raises StopIteration.
def next(self):
self.count += 1
if self.count < 4:
return self.count
else:
# A StopIteration exception is raised
# to signal that the iterator is done.
# This is caught implicitly by the 'for' loop.
raise StopIteration
def some_func():
return it()
for i in some_func():
print i
为了更深入地了解幕后发生的事情,
iterator = some_func()
try:
while 1:
print iterator.next()
except StopIteration:
pass
这更有意义还是更让人困惑?
我要指出,为了说明起见,这过于简单化。 )
TL; DR TR; TL; TDR
代替此:
def square_list(n):
the_list = [] # Replace
for x in range(n):
y = x * x
the_list.append(y) # these
return the_list # lines
这样做:
def square_yield(n):
for x in range(n):
y = x * x
yield y # with this one.
每当你发现自己从头开始编出一个清单时, 每一块都取而代之。
这是我第一次"啊哈"节奏节奏
收成是一种含糖的方式 说
构建一系列材料
相同行为 :
>>> for square in square_list(4):
... print(square)
...
0
1
4
9
>>> for square in square_yield(4):
... print(square)
...
0
1
4
9
不同的行为 :
产量是单行道,只能绕过一次。当一个函数有收益时,我们称它为发电机功能。循环者就是它的回报。这些术语是明亮的。我们失去了一个容器的方便,但获得一系列按需要计算并任意延长的能量。
是懒惰的, 它会推卸计算。 函数中含有收益的函数在调用时不会实际执行。 它返回一个循环器对象, 记得它留下的位置。 每次您在调用循环器时( 这发生在换环) 执行步数向下一个产数前进。 返回会提高停止输出并结束序列( 这是换圈的自然结束 ) 。
产量是多功能的。数据不必全部储存在一起, 它可以一次提供一次。 它可以是无限的 。
>>> def squares_all_of_them():
... x = 0
... while True:
... yield x * x
... x += 1
...
>>> squares = squares_all_of_them()
>>> for _ in range(4):
... print(next(squares))
...
0
1
4
9
如果您需要多个通行证,且系列不会太长,请在电话列表上填写:
>>> list(square_yield(4))
[0, 1, 4, 9]
英明地选择“产生”一词,因为这两个含义都适用:
产量——生产或供应(如农业)
...在系列中提供下一个数据
放弃或放弃(与政治权力一样)
...在传动器推进之前,将CPU执行。
又一个TRL;DR
列表中的迭代器 : 下一个 () 返回列表的下一个元素 。
迭代生成器: 下一个 () 将计算苍蝇上的下一个元素( 执行代码)
您可以通过下拨“无论流量如何复杂”,将产出/生成器视为手动运行外部控制流的一种方式(如继续循环一步),然后调用该输出/生成器作为手动运行外部控制流的一种方式。
注意 : 生成器不是一个正常的函数。 它会像本地变量( stack) 一样记住先前的状态 。 请参看其他答案或文章以详细解释 。 生成器只能重复一次 。 您可以不生产, 但不会是那么好, 所以它可以被视为“ 非常好” 的语言糖 。
发电机可以使个别经过处理的物品立即得到处理(不必等待整个收集过程的处理),下面的例子说明了这一点。
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