python - 树实现中的奇怪结果

时间:2015-12-15 06:42:03

标签: python python-2.7 tree

在python中编写一些脚本时,我编写了一个简单的类树结构。在测试之后,我得到了一个奇怪但有趣的结果;

假设我们实现了一个简单的树,每个节点都有一个子节点。然后,我们可以像这样实现它:

class node_1(object):
    def __init__(self, data = 0, child = None):
        self.data = data
        self.child = child

    def append(self, child):
        self.child = child

    def __str__(self):
        return '(box %s)' % str(self.data)

    def __repr__(self):
        return self.__str__()

当我们执行以下代码时:

root_1 = node_1(0)
root_1.append(node_1(1))
root_1.child.append(node_1(2))

print root_1, root_1.child, root_1.child.child

我们得到以下结果,我们期望:

(box 0) (box 1) (box 2)

现在让我们假设每个节点可以有多个子节点;如果我们像下面的代码那样实现它:

class node_2(object):
    def __init__(self, data = 0, childs = []):
        self.data = data
        self.childs = childs

    def append(self, *childs):
        map(self.childs.append, childs)

    def __str__(self):
        return '(box %s)' % str(self.data)

    def __repr__(self):
        return self.__str__()

然后是代码

root_2 = node_2(0)
root_2.append(node_2(1), node_2(2))
root_2.childs[0].append(node_2(3), node_2(4))

print root_2, root_2.childs, root_2.childs[0].childs

输出

(box 0) [(box 1), (box 2), (box 3), (box 4)] [(box 1), (box 2), (box 3), (box 4)]

,而不是

(box 0) [(box 1), (box 2)] [(box 3), (box 4)]

我猜测这与可迭代对象中项目的引用有关,但我无法弄清楚子节点的原因(精确)。 self.childs不仅包含它们的子节点,还包含兄弟节点甚至父节点。你能帮我理解为什么会出现这个结果吗?

(完整代码:https://github.com/Avantgarde95/share/blob/master/btest.py

[解决]

感谢他们提供的以及他提供的链接,我可以理解问题是由孩子= []'声明。根据链接,只有当python遇到' def'时,才会(重新)评估默认参数。关键词;所以,如果我设置默认参数' childs'在第一次调用self.append之后,一个可变对象(例如list),节点的所有self.childs将指向同一个对象。

以下代码现在运作良好:

class node(object):
    def __init__(self, data = 0, childs = None):
        self.data = data

        if childs is None:
            self.childs = []
        else:
            self.childs = child

    def append(self, *childs):
        map(self.childs.append, childs)

    def __str__(self):
        return '(box %s)' % str(self.data)

    def __repr__(self):
        return self.__str__()

执行

root = node(0)
root.append(node(1), node(2))
root.childs[0].append(node(3), node(4))

print root, root.childs, root.childs[0].childs

给出

(box 0) [(box 1) (box 2)] [(box 3) (box 4)]

0 个答案:

没有答案