1

重複の可能性:
Python の「最小の驚き」: 変更可能な既定の引数

次の 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]理由を理解するためのものではありません。毎回、毎回同じツリーになってしまうようです」.

4

1 に答える 1

4

これは、init を設定するとchildren = []、毎回新しいリストが作成されず、最初にリストが作成され、それ以外は同じリストが使用されるためです。それは動作を説明します。これらの場合、最善の方法は次のように書くことです

def __init__(self, ..., children = None):
    if children is None: children = []
于 2012-11-25T23:25:45.283 に答える