递归python函数中的持久对象

Posted

技术标签:

【中文标题】递归python函数中的持久对象【英文标题】:Persistent objects in recursive python functions 【发布时间】:2010-12-02 02:03:53 【问题描述】:

我正在尝试编写一个递归函数,该函数需要在递归时存储和修改一个对象(比如一个集合)。我应该在函数中使用全局名称吗?另一种选择是修改或继承函数参数的类,以便它可以保留这个持久对象,但我觉得它不优雅。如果我完全放弃递归,我也可以使用堆栈......

有没有一种pythonic的方式来做到这一点?发电机可以解决问题吗?

【问题讨论】:

这取决于任务。听起来发电机可以工作,但我不知道你在做什么,所以我不能确定。 【参考方案1】:

只需通过递归方法传递你的持久对象。

def recursivemethod(obj_to_act_on, persistent_obj=None):

    if persistent_obj == None:
        persistent_obj = set()

    # Act on your object

    return recursivemethod(newobj, persistent_obj)

【讨论】:

请修正缩进。通常我不会抱怨,但在 Python 中这很重要。 谢谢!在发布问题之前我已经看到了这种模式,但我想有些钉子需要更多的推动! [这是我的代码不起作用而不是模式] 也没有方法叫Set,它是set 不应该if persistent_obj == Noneif persisten_obj is None【参考方案2】:

对象通过引用传递。如果您只是修改一个对象,您可以在递归函数中执行此操作,并且更改将是全局可见的。

如果您需要在递归函数中分配一个变量并在函数返回后查看它,那么您不能只使用= 分配一个局部变量。您可以做的是更新另一个对象的字段。

class Accumulator: pass

def foo():
    # Create accumulator
    acc = Accumulator()
    acc.value = 0

    # Define and call a recursive function that modifies accumulator
    def bar(n):
        if (n > 0): bar(n-1)
        acc.value = acc.value + 1
    bar(5)

    # Get accumulator
    return acc.value

【讨论】:

这就像一个全局变量不是吗? foo 只是简单地为 bar 声明和初始化 acc。 @kavic 这是一个局部变量。该变量不在全局命名空间中,每次调用 foo 都有一个实例(不是一个全局实例)。 foo 不仅初始化 acc,它还从 acc 中检索最终值。【参考方案3】:

将集合作为参数传递给递归方法,然后在将其传递到下一步之前对其进行修改。复杂对象通过引用传递。

【讨论】:

【参考方案4】:

如果是容器(不是不可变数据类型),可以通过:

import random

def foo(bar=None, i=10):
    if bar is None:
        bar = set()
    if i == 0:
        return bar
    bar |= set(random.randint(1, 1000) for i in xrange(10))
    return foo(bar, i - 1)

random_numbers_set = foo()

(不要问我那是什么意思……我只是随便输入一些东西:P)

【讨论】:

【参考方案5】:

如果您传递的对象是可变的,那么在更深层次的递归中对其所做的更改将在更早的递归中看到。

【讨论】:

【参考方案6】:

    对函数使用全局变量。

    将对象作为累加器传递:

    def recurse(foo, acc=None):
        acc = 
        recurse(acc)
    

【讨论】:

以上是关于递归python函数中的持久对象的主要内容,如果未能解决你的问题,请参考以下文章

Python基础(10)_内置函数匿名函数递归

Python_面向对象_递归

python小功能-递归解析Json

python递归 及 面向对象初识及编程思想

06python 中的递归函数(python函数)

python基础----递归函数认识类和对象