【问题标题】:Creating a graph data structure in python using classes使用类在python中创建图形数据结构
【发布时间】:2018-09-22 02:36:39
【问题描述】:

我正在尝试创建某种类型的类,该类足够通用,可用于树和图。

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

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

    def add_children(self, list_of_children):
        for child in list_of_children:
            self.add_child(child)

def letterGraph():
    a = Node('A')
    b = Node('B')
    c = Node('C')
    d = Node('D')
    c = Node('C')
    e = Node('E')
    f = Node('F')
    g = Node('G')

    a.add_children([b, c])
    b.add_children([a, d, e])
    c.add_children([a, d])
    d.add_children([b, c, e, g, f])
    e.add_children([b, d, g])
    f.add_children([d, g])
    g.add_children([e, d, f])

    return a

它似乎可以很好地处理树,但对于图形,当它向当前节点添加一个子节点时,它也会将同一个子节点添加到当前节点的子节点。

示例:

当前节点:一个

a.add_children([b,c])

current_node.children: [b,c]

b.children: [b,c]`

【问题讨论】:

  • def __init__(self, value, children=[]): 在 Python 中非常危险,因为默认参数是在函数定义时计算的,而不是在调用函数时(就是这样一个容易犯的错误)。所以默认总是同一个数组。使用...children=None,如果没有children,则children = []。 Official docs link
  • +1 对上述评论。一般来说,对于默认参数,最佳实践是只使用不可变对象;否则使用None 并在函数/方法块中替换它们。

标签: python python-3.x data-structures graph-algorithm


【解决方案1】:

我个人根本不会在构造函数中调用它。你不使用所以你为什么要在那里?

在测试时使用__repr__ 使其更具可读性也很有帮助。

class Node:
    def __init__(self, value):    # Take children out of constructor
        self.value = value
        self.children = []     # Initialise children in the function

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

    def add_children(self, list_of_children):
        for child in list_of_children:
            self.add_child(child)

    def __repr__(self): 
        return self.value    # I am not a machine 

def letterGraph():
    a = Node('A')
    b = Node('B')
    c = Node('C')
    d = Node('D')
    c = Node('C')
    e = Node('E')
    f = Node('F')
    g = Node('G')

    a.add_children([b, c])
    b.add_children([a, d, e])
    c.add_children([a, d])
    d.add_children([b, c, e, g, f])
    e.add_children([b, d, g])
    f.add_children([d, g])
    g.add_children([e, d, f])

    print(a.children)
    print(b.children)


letterGraph()

【讨论】:

  • 我以其他方式使用了 children 变量,而不是我在此处给出的示例。这对我不起作用。
【解决方案2】:

这是我在@amadan 的帮助下修复的方法

infinity = float('inf')

class Node:
    def __init__(self, value, children = None, depth=None):
        self.value = value
        self.children = children
        self.depth = depth

    def add_child(self, child, depth= None):
        if self.children is None:
            self.children = [child]
            self.depth = depth
        else:
            self.children.append(child)

    def add_child_by_value(self, value):
        self.children.add_child(Node(value))

    def add_children(self, list_of_children):
        for child in list_of_children:
            self.add_child(child)

    def is_leaf(self):
        return self.children is None

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-13
    • 1970-01-01
    相关资源
    最近更新 更多