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链接。
python 的输出与返回语句类似,但有些差异除外。如果要从函数返回多个值,返回语句将把所有值都作为列表返回,并将其存储在调用符块的内存中。但如果我们不想使用额外的内存,会怎样?相反,我们需要在需要时从函数中获取该值。这是产出的来源。考虑以下函数:
def fun():
yield 1
yield 2
yield 3
打电话的人是:
def caller():
print ('First value printing')
print (fun())
print ('Second value printing')
print (fun())
print ('Third value printing')
print (fun())
上述代码段(调用函数),如果调用,产出:-
First value printing
1
Second value printing
2
Third value printing
3
从上文可以看出, 产出返回其调用器的值, 但当函数再次调用时, 它不会从第一个语句开始, 而是从产出后右侧的语句开始。 在上述示例中, “ 第一值打印” 打印, 函数被调用。 1 被回传并打印。 然后, 打印“ 第二值打印” , 并再次调用有趣 () 。 它不打印 1 (第一个语句) , 而是返回 2 , 也就是说, 仅从产出 1 之后的语句 。 同样的程序会进一步重复 。
所有的答案都是伟大的, 但对于新人来说有点困难。
我猜你已经得知回程声明了
作为类比,回归和收益是双胞胎。 回归意味着“ 回归和停止 ” , 而“ 回归”则意味着“回归,但继续 ” 。
尝试获得一份有回报的 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> 。
最后,作为格罗克语的比喻:
双胞胎名单和发电机是双胞胎
下面是浅白语言的例子。我将提供高层次人类概念与低层次Python概念之间的对应关系。
我想用数字序列操作, 但我不想用这个序列的创建来烦恼我自己, 我只想专注于我想做的操作。 因此, 我做以下工作:
我打电话给你并告诉你,我想要一个以特定方式计算的数字序列,我告诉你算法是什么。 这个步骤对应着定义发电机的函数, 也就是包含一个产出的函数。 稍后我告诉你, “ 好, 准备好告诉我数字的序列 ” 。 这个步骤对应着调用发电机的函数, 返回一个发电机对象。 注意不要告诉我任何数字; 你只是拿起你的纸张和铅笔。 我问你, “ 请告诉我下一个数字 ” , 然后你告诉我第一个数字; 之后, 你等着我问你下一个数字。 这是你的任务, 也就是确定你所在的位置, 你已经说过的数字, 下一个数字是什么。 我不在乎细节。 这个步骤相当于在发电机对象上调用下一个( 发电机) 号码的方法。 ( Python 2, next) 注意, 这是一个发电机对象的方法; 在 Python 3, 它被命名为...
这是生成器所做的( 包含一个产值的函数 ) ; 它开始在第一个( ) 上执行, 当它做一个产值时暂停, 当要求下一个( ) 值时, 它会从最后一点继续 。 它的设计完全符合 Python 的循环协议, 协议描述如何按顺序要求值 。
迭代协议最著名的用户是 Python 的命令用户。 所以, 当你做 :
for item in sequence:
序列是否是一个列表、字符串、字典或上述生成对象并不重要;结果是一样的:您逐个阅读序列中的项目。
请注意,定义含有产出关键字的函数不是创建生成器的唯一方法;它只是创建生成器的最简单的方法。
欲知更准确的信息,请阅读Python文件中的迭代机类型、产量说明和发电机。