Python lambda表达式组成迭代器脚本

时间:2013-05-17 12:21:44

标签: python lambda-calculus

我正在编写一个python脚本,它应该采用一系列函数,写成lambda表达式,并返回所有函数的组合,但是,我在脚本中有一个箭头,可能是因为我的方式使用lambda表达式。看起来即使我给返回的函数一个数字值,我得到一个函数,而不是一个数字。这就是我写的:

def compose1(lst):
    if lst == []:
        return lambda x: x
    else:
        temp = (lst[len(lst)-1])
        for i in range(len(lst)-2,-1,-1):
            temp = lambda x: lst[i](temp)
        return lambda x: temp

这是我写过的函数的一个尝试,它说我有一个错误。

f = compose1([lambda x: x+1, lambda x: x*2, lambda x: x-1])
for x in range(10):
    assert (f(x) == 1 + (x - 1) * 2)
f = compose1([lambda x: x-1, lambda x: x*2, lambda x: x+1])
for x in range(10):
    assert (f(x) == (x + 1) * 2) - 1

我会对这个问题进行一些抨击.. 谢谢:))

4 个答案:

答案 0 :(得分:3)

def compose(*funcs):
    """
    compose(func[,...[, func]]) -> function

    Return the composition of functions.
    For example, compose(foo, bar)(5) == foo(bar(5))
    """
    if not all(callable(func) for func in funcs):
        raise TypeError('argument must be callable')
    funcs = funcs[::-1]

    def composition(*args, **kwargs):
        args = funcs[0](*args, **kwargs)
        for func in funcs[1:]:
            args = func(args)
        return args
    return composition

f = compose(*[lambda x: x+1, lambda x: x*2, lambda x: x-1])
for x in range(10):
    assert f(x) == (1 + (x - 1) * 2)
f = compose(*[lambda x: x-1, lambda x: x*2, lambda x: x+1])
for x in range(10):
    assert f(x) == ((x + 1) * 2) - 1

答案 1 :(得分:1)

这里的问题是你的逻辑。

for i in range(len(lst)-2,-1,-1):
    temp = lambda x: lst[i](temp)
return lambda x: temp

这会将temp设置为一个函数。 lst是一个函数列表,lst[i]是一个函数。你调用它,给出一个值,然后用lambda创建一个新函数。然后返回一个提供该功能的函数。

你的返回值是一个函数,它给出一个函数,它给出一个值,因此你的问题。

请注意,此代码还有其他问题。例如,if lst == []:应为if not lst:。您也不应该按索引进行迭代,而是按照Python的设计迭代值。我实际上无法弄清楚你想用你的代码实现什么,这显示了索引迭代的难度。

您的代码目前正在执行此操作:

  • 如果没有值,则返回一个返回第一个参数的函数。
  • 如果有一个值,请返回列表中的函数。
  • 如果有许多值,则返回一个函数,该函数返回一个函数,该函数返回通过运行列表中的第一个函数而检索的第一个值。

我不确定你要做什么,但我很确定不是这样。

答案 2 :(得分:1)

看起来你的循环只是重新实现了reduce的功能。这是功能组合问题的功能性视图:

def compose1(fnlist):
    if not fnlist:
        return lambda x: x

    # compose 1 function of x from two others
    def compose2fns(fn1, fn2):
        return lambda x : fn1(fn2(x))
    # or if you really love lambdas
    # compose2fns = lambda fn1,fn2: lambda x: fn1(fn2(x))

    # use reduce to cumulatively apply compose2fns to the functions
    # in the given list
    return reduce(compose2fns, fnlist)

这可以很好地通过你的测试。

CODE GOLF: 我无法抗拒,这是一个单行,甚至包括你检查空输入列表:

compose1 = lambda fnlist: reduce(lambda fn1,fn2: lambda x : fn1(fn2(x)), 
                                  fnlist or [lambda x:x])

答案 3 :(得分:0)

我喜欢这种语法:

f = do (lambda x: x-1) (lambda x: x*2) (lambda x: x+1)

for x in range(10):
    assert f(x) == 1 + (x - 1) * 2

实施非常简单:

class do(object):
    def __init__(self, x):
        self.fns = [x]
    def __call__(self, x):
        if callable(x):
            self.fns.append(x)
            return self
        for f in self.fns:
            x = f(x)
        return x