Python对象标识

时间:2012-11-25 23:20:40

标签: python

  

可能重复:
  “Least Astonishment” in Python: The Mutable Default Argument

我有以下Python代码:

class Node(object):
    def __init__(self, name, children = []):
        self.name = name
        self.children = children

    def add_child(self, child):
        self.children.append(child)

    def __str__(self):
        return self.name

def create_tree(num_vertices):
    vs = [Node(str(i)) for i in range(num_vertices)]
    for i in range(num_vertices):
        if 2 * i + 1 < num_vertices:
            vs[i].add_child(vs[2 * i + 1])
        if 2 * i + 2 < num_vertices:
            vs[i].add_child(vs[2 * i + 2])

    return vs[0]

def bfs(top_node, visit):
    """Breadth-first search on a graph, starting at top_node."""
    visited = set()
    queue = [top_node]
    while len(queue):
        curr_node = queue.pop(0)   # Dequeue
        visit(curr_node)           # Visit the node
        visited.add(curr_node)

        # Enqueue non-visited and non-enqueued children
        queue.extend(c for c in curr_node.children
                     if c not in visited and c not in queue)

def visit(tree):
    print tree

现在我在IDLE中进行以下调用:

>>> bfs(create_tree(3), visit)
0
1
2
>>> bfs(create_tree(3), visit)
0
1
2
1
2

即使我每次尝试创建一个新树,我似乎每次都以相同的树结束(每次都添加新节点)。这是为什么?在create_tree中,我正在为每个函数调用创建一个新列表。

(顺便说一下,这不是家庭作业。在 Think Complexity 中练习4.2,我正在阅读这篇文章以获得乐趣,而练习并不是要弄明白为什么“[e] ven虽然我每次尝试创建一个新树,但我似乎每次都会使用相同的树。“(问题是要找出为什么bfs代码效率低下而且我知道答案。))

1 个答案:

答案 0 :(得分:4)

这是因为如果你在init children = []中设置它不会每次创建一个新列表,它会在第一次创建一个列表而其他时候使用相同的列表;这解释了这种行为。在这些情况下,最好的办法是写

def __init__(self, ..., children = None):
    if children is None: children = []