首页 > 解决方案 > 从普通函数创建生成器函数

问题描述

我正在http://www.dabeaz.com/generators/上阅读有关生成器的信息 (这是非常好的、内容丰富的文章,即使它是 ppt 幻灯片)

它有以下部分关于creating geneators

任何单参数函数都容易变成生成器函数

def generate(func):
 def gen_func(s):
   for item in s:
     yield func(item)
 return gen_func

• 例子:

gen_sqrt = generate(math.sqrt)
for x in gen_sqrt(range(100)):
 print(x)

我看不出这张幻灯片的意义所在。(在幻灯片的 114p 上)

不只是(math.sqrt(e) for e in range(100))

他在完成什么generate功能?

标签: pythongenerator

解决方案


这种高阶函数的要点是允许在不同的时间/地点选择函数的多个输入:

def filter_lines(f,filt):
  with open(f) as f:
    for l in f:
      print(' '.join(list(filt(map(float,l.split())))))

这可以接受任何类型的可迭代转换器filt,例如

def ints(it):
  for f in it:
    if f==int(f): yield f

结果generate:_

filter_lines("…",ints)
filter_lines("…",list)  # the identity: print all
filter_lines("…",generate(math.sqrt))
filter_lines("…",generate(abs))

因此我们可以看到generate 一个元素的函数转换为元素的可迭代函数。(这就是“变成生成器函数”的意思。)我们可以更进一步:

import functools
filter_lines("…",functools.partial(map,math.sqrt))

从中我们可以得出结论,generate它本身等价于functools.partial(functools.partial,map)。像这样应用partial两次会将参数列表一分为二,将普通函数更改为高阶函数。


推荐阅读