Ton*_*roy 9 python lambda yield generator
更新:示例现在列出所需的结果(下方以粗体显示)
我发现自己编写了许多搜索一些数据的函数,我想让调用者在找到匹配项时指定行为:它们可能会打印出一些内容或将其添加到其中一个数据结构中,但也非常希望能够可选地返回找到的数据以进一步传输,存储或处理.
def find_stuff(visitor): # library search function
for x in (1, 2, 3, 4, 5, 6):
visitor(x)
Run Code Online (Sandbox Code Playgroud)
首次客户使用:
def my_visitor(x): # client visitor functions (also often use lambdas)
if x > 3:
yield x / 2 #>>> WANT TO DO SOMETHING LIKE THIS <<<#
results = find_stuff(my_visitor) # client usage
Run Code Online (Sandbox Code Playgroud)
results
应该产生4/2,5/2,然后是6/2 ......即2,2,3.
第二个客户使用:
def print_repr_visitor(x):
print repr(x)
find_stuff(print_repr_visitor) # alternative usage
Run Code Online (Sandbox Code Playgroud)
应打印1 2 3 4 5 6(单独的行)但不产生任何结果
但是,它yield
并没有在"结果"中创建一个生成器(至少使用python 2.6.6,我坚持使用).
我一直在乱砍这个,经常这样......
def find_stuff(visitor):
for x in (1, 2, 3, 4, 5):
val = visitor(x)
if val is not None:
yield val
Run Code Online (Sandbox Code Playgroud)
...或者有时,当访问者参数列表很难输入太多次...
def find_stuff(visitor):
for x in (1, 2, 3, 4, 5):
val = visitor(x)
if val == 'yield':
yield x
elif val is not None:
yield val
Run Code Online (Sandbox Code Playgroud)
这些"解决方案"不仅笨拙 - 需要来自"查找"例程的显式内置支持 - 它们会从访问者可以回馈给顶级调用者的结果集中删除哨兵值...
在简洁,直观,灵活,优雅等方面有更好的选择吗?
谢谢!
在Python 3中,您可以使用yield from
从子生成器中生成项:
def find_stuff(visitor):
for x in (1, 2, 3, 4, 5):
yield from visitor(x)
Run Code Online (Sandbox Code Playgroud)
在Python 2中,您必须遍历子生成器.这需要更多的代码并且不处理一些边缘情况,但它通常足够好:
def find_stuff(visitor):
for x in (1, 2, 3, 4, 5):
for item in visitor(x):
yield item
Run Code Online (Sandbox Code Playgroud)
边缘情况就像尝试将send
值或throw
异常放入子生成器中一样.如果您不使用协同程序功能,则可能不需要担心它们.