是否建议用Python编写递归函数

桑杰

作为实验的一部分,我在python中编写了一个Verilog(逻辑门及其连接描述)。

我遇到了堆栈限制问题,因此我做了一些阅读,发现Python没有“尾部调用优化”功能(即,随着递归的进行而动态删除堆栈条目)

在这方面,我主要有两个问题:

1)如果我增加了堆栈限制,这sys.setrecursionlimit(15000)是否会影响时间性能(内存-我不在乎)?

2)假设我可以在没有堆栈跟踪的情况下生存,有什么办法可以绕过此限制。
我之所以这样问是因为Verilog主要处理状态机,可以使用递归函数以一种优雅的方式来实现它。

此外,如果我可以添加(在递归函数调用的情况下),如果有错误,我将更多地依赖导致此错误的输入,而不是堆栈跟踪。

我是Python的新手,所以也许专家可能会认为Python堆栈跟踪对于调试递归函数调用非常有用...如果是这种情况,我很乐于学习如何做。

最后,建议使用Python编写递归函数,还是应该转向其他语言?

如果有任何变通办法,使得我可以继续将python用于递归函数,我想知道是否有任何性能影响(尽管我可以进行性能分析)。

烈瑞恩

2)假设我可以在没有堆栈跟踪的情况下生存,有什么办法可以绕过此限制。我之所以这样问是因为Verilog主要处理状态机,可以使用递归函数以一种优雅的方式来实现它。

有一种方法可以避免尾部调用而无需过多更改现有逻辑,只需重写尾部调用以返回一个thunk,然后使用蹦床来调用该thunk。如果需要在过渡之间传递复杂的状态,则可以使用延续传递样式来传递它们。这种编写代码的样式非常适合编写状态机。

假设您从fizzbuzz状态机的此递归实现开始,该示例使用尾调用将控制权传递给下一个转换,则示例可能更清晰:

def start():
    return increment(0)

def fizz(n):
    print 'fizz'
    return increment(n)

def buzz(n):
    print 'buzz'
    return increment(n)

def fizzbuzz(n):
    print 'fizzbuzz'
    return increment(n)

def increment(n):
    n = n + 1
    if n > 100:
        return terminate()
    elif n % 3 == 0 and n % 5 == 0: 
        return fizzbuzz(n)
    elif n % 3 == 0: 
        return fizz(n)
    elif n % 5 == 0:
        return buzz(n)
    else:
        print n
        return increment(n)

def terminate():
    raise StopIteration

try:
    start()
except StopIteration:
    pass

为了避免出现尾部调用,您只需将所有尾部调用包装在lambda中(或替代地,functools.partial)并添加一个蹦床:

def start():
    return lambda: increment(0)

def fizz(n):
    print 'fizz'
    return lambda: increment(n)

def buzz(n):
    print 'buzz'
    return lambda: increment(n)

def fizzbuzz(n):
    print 'fizzbuzz'
    return lambda: increment(n)

def increment(n):
    n = n + 1
    if n > 2000:
        # strictly speaking, transitions that takes no arguments
        # like terminate don't need to be wrapped in lambda
        # this is added here only for symmetry with others
        return lambda: terminate()
    elif n % 3 == 0 and n % 5 == 0: 
        return lambda: fizzbuzz(n)
    elif n % 3 == 0: 
        return lambda: fizz(n)
    elif n % 5 == 0:
        return lambda: buzz(n)
    else:
        print n
        return lambda: increment(n)

def terminate():
    raise StopIteration

def trampoline(func): 
    try:
        while True:
            func = func()
    except StopIteration:
        pass

trampoline(lambda: start())

现在,您可以拥有更多的fizzbuzz,而无需达到递归限制。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

用Python编写递归函数

来自分类Dev

Python编写递归函数

来自分类Dev

用C编写递归函数

来自分类Dev

在Python 3.0上编写递归函数

来自分类Dev

Python。编写一个函数来递归地测试一个单词是否是回文

来自分类Dev

用python编写数学函数

来自分类Dev

是否可以使用递归技术编写组合函数?

来自分类Dev

编写递归函数

来自分类Dev

编写一个函数,用递归函数检查一个数是否是一个正方形

来自分类Dev

用python编写字典字典的函数

来自分类Dev

Python是否允许递归__iter__函数?

来自分类Dev

是否可以用C ++编写通用算术函数?

来自分类Dev

编写递归模板haskell函数

来自分类Dev

如何正确编写递归函数?

来自分类Dev

是否建议在python函数中使用print语句而不是返回

来自分类Dev

是否建议在python函数中使用print语句而不是返回

来自分类Dev

用R编写函数

来自分类Dev

用R编写函数

来自分类Dev

用球拍初学者编写递归函数时卡住了吗?

来自分类Dev

递归函数是否比非递归函数慢

来自分类Dev

用Python的方式编写接受多种类型的库函数?

来自分类Dev

用Python编写(具有整数的函数的无穷和)

来自分类Dev

如何为组合编写递归函数

来自分类Dev

尝试用Java编写递归函数

来自分类Dev

未能编写异步递归迭代函数

来自分类Dev

如何在MoonScript中编写递归函数?

来自分类Dev

尝试在球拍中编写递归函数

来自分类Dev

在Haskell中编写递归inRange函数

来自分类Dev

如何编写此递归Haskell函数