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链接。
所有的答案都是伟大的, 但对于新人来说有点困难。
我猜你已经得知回程声明了
作为类比,回归和收益是双胞胎。 回归意味着“ 回归和停止 ” , 而“ 回归”则意味着“回归,但继续 ” 。
尝试获得一份有回报的 num_ 列表 。
def num_list(n):
for i in range(n):
return i
运行它:
In [5]: num_list(3)
Out[5]: 0
你看,你只得到一个数字,而不是一个他们的名单。返回永远不允许你快乐地获胜,只要执行一次就退出。
产生结果
将返回替换为产出 :
In [10]: def num_list(n):
...: for i in range(n):
...: yield i
...:
In [11]: num_list(3)
Out[11]: <generator object num_list at 0x10327c990>
In [12]: list(num_list(3))
Out[12]: [0, 1, 2]
现在,你赢得了所有的数字。
与一次运行和停止的返回相比, 一次运行和一次运行, 一次运行和一次运行。 您可以将返回解释为一个返回, 一次返回作为全部返回。 这叫“ 易动 ” 。
再多走一步,我们就可以重新写出回报的收益声明
In [15]: def num_list(n):
...: result = []
...: for i in range(n):
...: result.append(i)
...: return result
In [16]: num_list(3)
Out[16]: [0, 1, 2]
这是关于产量的核心。
列表返回输出与目标产出的区别是:
您总是可以从列表对象中获取 [0, 1, 2] , 但只能从“ 对象输出输出” 中提取一次 。 因此, 它有一个新的名称生成对象, 如 Out[ 11] 所示 : <generator 对象 num_ list at 0x10327c990> 。
最后,作为格罗克语的比喻:
双胞胎名单和发电机是双胞胎
从方案拟订的角度来看,迭代器是作为散装件执行的。
为实施同时执行的迭代器、发电机和线形集合等,人们使用发往有调度员的关闭对象的电文,用发件人对“信息”的回答。
"下一步"是给一个封口发送的信息 由"标准"电话创建
有多种方法可以实施此计算。 我使用了突变, 但可以通过返回当前值和下一个生成者( 使其具有优先透明度 ) , 进行这种不发生突变的计算。 鼠标使用一些中间语言对初始程序进行一系列转换, 其中之一是将产出操作者转换为使用更简单的操作员的某种语言。
这是如何重写产量的演示, 它使用 R6RS 的结构, 但语义与 Python 的相同 。 这是相同的计算模式, 只需要修改语法, 才能使用 Python 的 产量重写 。
- (define gen (lambda (l) (define gen (lambda (l)) (define emple (lambda (lambda () ()) (if (null? l)) 'END (let ((v (car l))(set))(l (cdr))) (lambda (m) (cket m) (case m ('yield (yeld)(yeld))('ield))('iint (lamb) (lambda (lab) (lambda (data) (data) (l data))) ())) ) - (define 流 (gen 'ield (gen'(1,2 3 ) )) - (流 (流 ield) ) ) - (Live END - (Slead) (流 (流 ) (流 ) (流 (流 流 (流 流 流 流 流 流 ) 'ield) 'end - >
在 Python 生成器( 一种特殊的迭代器) 中, 生成一系列的值, 产出关键字与 发电机功能的返回关键字相似 。
另一个令人着迷的是 生成关键词的方法 是保存生成功能的状态。
因此,我们可以设定一个数字 以不同的数值 每一次发电机产生时。
以下是一个例子:
def getPrimes(number):
while True:
if isPrime(number):
number = yield number # a miracle occurs here
number += 1
def printSuccessivePrimes(iterations, base=10):
primeGenerator = getPrimes(base)
primeGenerator.send(None)
for power in range(iterations):
print(primeGenerator.send(base ** power))
简单解答
当函数包含至少一个输出语句时,函数自动成为生成函数。当您调用生成函数时, python 在生成函数中执行代码,直到生成语句发生。 当您调用生成函数时, python 继续从冻结位置执行生成函数中的代码,直到生成语句发生反复发生。 生成函数执行代码,直到生成函数在没有生成语句的情况下运行结束。
基准基准基准基准基准基准基准
创建列表并返回它 :
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
摘要摘要摘要
生成器函数需要稍多一点时间来执行, 而不是返回列表但少用内存的函数 。
- 功能 - 返回。
发电机 -- -- 产量(含有一个或多个产量和零或更多回报率)。
names = ['Sam', 'Sarah', 'Thomas', 'James']
# Using function
def greet(name) :
return f'Hi, my name is {name}.'
for each_name in names:
print(greet(each_name))
# Output:
>>>Hi, my name is Sam.
>>>Hi, my name is Sarah.
>>>Hi, my name is Thomas.
>>>Hi, my name is James.
# using generator
def greetings(names) :
for each_name in names:
yield f'Hi, my name is {each_name}.'
for greet_name in greetings(names):
print (greet_name)
# Output:
>>>Hi, my name is Sam.
>>>Hi, my name is Sarah.
>>>Hi, my name is Thomas.
>>>Hi, my name is James.
发电机看起来像一个函数,但行为举止却像一个迭代器。
发件人继续从它所在的位置执行 。 恢复后, 函数在最后产值运行后立即继续执行 。 这允许它的代码在一段时间内生成一系列的值, 代之以它们一次性计算全部值, 然后把它们像列表一样送回去 。
def function():
yield 1 # return this first
yield 2 # start continue from here (yield don't execute above code once executed)
yield 3 # give this at last (yield don't execute above code once executed)
for processed_data in function():
print(processed_data)
#Output:
>>>1
>>>2
>>>3
注:放弃不应在尝试中.最终建造。