在Python中追加递归方法的最佳方法是什么?

时间:2013-06-03 02:36:16

标签: python recursion

在下面的代码中,我试图将字符串'1/2/3/4/5/6 /'解析为层次结构树,期望输出应该是这样的:

# 1 -> 2 
# 2 -> 3
# 3 -> 4
# 4 -> 5
# 5 -> 6

但它返回:

# 1 -> [2, 3, 4, 5, 6]

在我打印一些变量之后,我找到了原因,变量'a1'不仅适用于第一个'a1',而且代表所有名为'a1'的变量,每个调用方法,它产生一个'a1'变量,并对其进行操作。 Python不喜欢其他OO语言,'a1'预计只是当前调用中唯一的变量。所以我的问题是,在Python中解决这类问题的最佳方法是什么?

class A(object):
    name = ''
    children = []

    def __repr__(self):
        return '%s -> %s' % (self.name, self.children)

def recurse(a1, s):
    if len(s) == 0: return

    s1 = s[0:s.find('/')]
    a1.name = s1
    print 's1: %s' % (s1)

    s2 = s[s.find('/') + 1:]
    print 's2: %s' % (s2)

    a2 = A()
    a1.children.append(a2) # Problem: why all child append into variable 'a' and all children too?
    # print 'locals() -> ', locals()    when I print locals(), I got the reason, but what's the best way to fix the problem?
    recurse(a2, s2)

a = A()
recurse(a, '1/2/3/4/5/6/') # input string required to ends with '/'

# expect: 
# 1 -> 2 
# 2 -> 3
# 3 -> 4
# 4 -> 5
# 5 -> 6

print a

2 个答案:

答案 0 :(得分:4)

您的孩子是一个类属性,因此所有实例都将共享和修改相同的列表

class A(object): 
    name = ''                      # these are class
    children = []                  # attributes

您应该为每个实例提供自己的列表

class A(object):
    def __init__(self):
        self.name = ''             # these are instance
        self.children = []         # attributes

答案 1 :(得分:1)

由于您将每个节点作为子节点添加到上一个节点,因此您将获得链式关系。您可以使函数返回节点列表:

class A(object):
    def __init__(self,name):
        self.name = name
        self.children = []
    def __repr__(self):
        return '%s -> %s' % (self.name, self.children)

def recurse(s,l=[]):
    v = s.split("/")
    if len(v) < 3: return
    a1,a2 = A(v[0]), A(v[1])
    a1.children.append(a2)
    v.pop(0)
    l.append(a1)
    recurse("/".join(v),l)
    return l

for i in recurse('1/2/3/4/5/6/'):
    print i

输出:

1 -> [2 -> []]
2 -> [3 -> []]
3 -> [4 -> []]
4 -> [5 -> []]
5 -> [6 -> []]