【问题标题】:Python: nested lambdas -- `s_push: parser stack overflow Memory Error`Python:嵌套 lambdas --`s_push:解析器堆栈溢出内存错误`
【发布时间】:2012-10-22 06:05:59
【问题描述】:

我最近偶然发现了this article,它描述了如何在 Ruby 中仅使用 Procs 来编写 FizzBu​​zz,由于我很无聊,我认为尝试在 Python 中使用 lambda 实现同样的东西会很好。

我到了使用嵌套函数创建数字的部分,并编写了以下 Python 脚本:

#!/usr/bin/env python

zero  = lambda p : (lambda x: x)
one   = lambda p : (lambda x: p(x))
two   = lambda p : (lambda x: p(p(x)))
three = lambda p : (lambda x: p(p(p(x))))
five  = lambda p: (lambda x: p(p(p(p(p(x))))))

fifteen = lambda p : (lambda x: p(p(p(p(p( \
                                p(p(p(p(p( \
                                p(p(p(p(p(x))))))))))))))))


hundred = lambda p: (lambda x: p(p(p(p(p(p(p(p(p(p( \
                               p(p(p(p(p(p(p(p(p(p( \
                               p(p(p(p(p(p(p(p(p(p( \
                               p(p(p(p(p(p(p(p(p(p( \
                               p(p(p(p(p(p(p(p(p(p( \
                               p(p(p(p(p(p(p(p(p(p( \
                               p(p(p(p(p(p(p(p(p(p( \
                               p(p(p(p(p(p(p(p(p(p( \
                               p(p(p(p(p(p(p(p(p(p( \
                               p(p(p(p(p(p(p(p(p(p(x)))))))))))))))))))))))))))) \
                                                     ))))))))))))))))))))))))))) \
                                                     ))))))))))))))))))))))))))) \
                                                     )))))))))))))))))))

def to_int(func):
    return func(lambda n: n + 1)(0)

print to_int(zero)
print to_int(one)
print to_int(two)
print to_int(three)
print to_int(five)
print to_int(fifteen)
print to_int(hundred)

数字 0 到 15 可以正常工作,但如果我尝试创建数字 100,由于以下错误,文件将无法运行:

s_push:解析器堆栈溢出
内存错误

我必须把它注释掉才能让文件运行。

这种糟透了——有什么办法可以绕过这个限制,这样我就可以任意嵌套 lambda 和函数调用,而不会导致 Python 崩溃和内存不足?

或者,我可以使用某种 lambda 演算技巧来表达数字 100,而无需太多嵌套函数?

【问题讨论】:

    标签: python stack-overflow lambda-calculus


    【解决方案1】:

    不用这么多嵌套函数就表达数字100?

    给你:

    >>> test = lambda f: f(lambda x: x + 1)(0)
    >>> z = lambda f: lambda x: x
    >>> test(z)
    0
    >>> succ = lambda n: lambda f: lambda x: f(n(f)(x))
    >>> _1 = succ(z)
    >>> test(_1)
    1
    >>> _2 = succ(_1)
    >>> test(_2)
    2
    >>> plus = lambda m: lambda n: lambda f: lambda x: m(f)(n(f)(x))
    >>> _3 = plus(_1)(_2)
    >>> test(_3)
    3
    >>> mult = lambda m: lambda n: lambda f: lambda x: m(n(f))(x)
    >>> _6 = mult(_2)(_3)
    >>> test(_6)
    6
    >>> _5 = plus(_2)(_3)
    >>> _25 = mult(_5)(_5)
    >>> _4 = plus(_2)(_2)
    >>> _100 = mult(_25)(_4)
    >>> test(_100)
    100
    >>> 
    

    【讨论】:

      【解决方案2】:

      看起来如果不重新编译 Python 是不可能的。解析器堆栈大小由parser.h 中的常量 MAXSTACK 设置。您可以增加此值并重新编译以增加限制。请参阅 http://bugs.python.org/issue3971http://mail.python.org/pipermail/python-list/2012-March/621555.html

      【讨论】:

        【解决方案3】:

        从 lambda 演算的角度来看,可以使用以下函数来增加数字:

        succ = lambda n: lambda p: lambda x: p(n(p)(x))
        

        然后,one = succ(zero)two = succ(one) 等等。

        【讨论】:

          猜你喜欢
          • 2023-04-11
          • 2015-11-24
          • 1970-01-01
          • 1970-01-01
          • 2011-09-26
          • 1970-01-01
          • 1970-01-01
          • 2014-01-26
          • 2019-02-16
          相关资源
          最近更新 更多