在Python中保存自定义类实例的状态更改

时间:2018-08-12 06:33:38

标签: python python-3.x tree

我很难理解为什么我的print(Node(3).value)打印0的原因。有什么想法吗?

运行此代码时,我得到

First: 6 Value: 8 Children: [9]
First: 8 Value: 23 Children: [9]
First: 3 Value: 3 Children: [5]
First: 6 Value: 8 Children: [7]
First: 4 Value: 20 Children: [8]
First: 1 Value: 17 Children: [8]
First: 8 Value: 23 Children: [10]
First: 5 Value: 11 Children: [8]
First: 1 Value: 17 Children: [2]
0

有什么想法吗?我知道我不会将节点保存在任何地方,但是我无法解决这个问题。 任何帮助将不胜感激,谢谢!

# Complete the primeQuery function below.
n = 10
first = [6, 8, 3, 6, 4, 1, 8, 5, 1]
second = [9, 9, 5, 7, 8, 8, 10, 8, 2]
values = [17, 29, 3, 20, 11, 8, 3, 23, 5, 15]
queries = [1, 8, 9, 6, 4, 3]


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

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

    def setValue(self, givenV):
        self.value = givenV


def primeQuery(n, first, second, values, queries):
    i = 0
    while i < n - 1:
        f = Node(first[i], values[first[i] - 1])

        s = Node(second[i], values[second[i] - 1])

        f.addChild(s.data)

        print(f"First: {f.data} Value: {f.value} Children: {f.children}")

        i += 1

    print(Node(3).value)


primeQuery(n, first, second, values, queries)

1 个答案:

答案 0 :(得分:0)

声明

Node(3).value

创建Node对象,并将data设置为3并将value设置为0(默认参数),因此当您获得其{{ 1}}返回value

如果要创建0对象,然后重新使用它们,则应将它们存储在某种容器中。

假设

  • Node字段是data的可哈希唯一标识符,
  • 如果已创建Node,并且我们要传递不同的Node-旧的value仍然存在

我在这里至少看到2种方法:

  • 在顶层创建容器,在创建时向其显式添加value,然后像这样

    Node

    给我们

    def primeQuery(n, first, second, values, queries):
        i = 0
        # top-level container of ``Node``s
        nodes = {}
    
        def get_or_create_node(data, value):
            try:
                # trying to access already created ``Node``
                result = nodes[data]
            except KeyError:
                # no ``Node`` found, create it...
                result = Node(data, value)
                # ... and register
                nodes[data] = result
            return result
    
        while i < n - 1:
            f = get_or_create_node(first[i], values[first[i] - 1])
            s = get_or_create_node(second[i], values[second[i] - 1])
    
            f.addChild(s.data)
    
            print(f"First: {f.data} Value: {f.value} Children: {f.children}")
    
            i += 1
    
        print(nodes[3].value)
        # we can return ``nodes`` here if we want to use them outside of given function
    
  • 先前方法的扩展:使用全局函数限制First: 6 Value: 8 Children: [9] First: 8 Value: 23 Children: [9] First: 3 Value: 3 Children: [5] First: 6 Value: 8 Children: [9, 7] First: 4 Value: 20 Children: [8] First: 1 Value: 17 Children: [8] First: 8 Value: 23 Children: [9, 10] First: 5 Value: 11 Children: [8] First: 1 Value: 17 Children: [8, 2] 3 的创建,该函数缓存已创建的函数:

    Node

    注释:此处我们使用带有可变默认参数的“ hack”,更多信息可能在this thread中找到)

    然后到处需要创建/访问# in module namespace def get_or_create_node(data, value=0, *, # hack, see **note** cache={}): # we've moved class definition inside of a function to restrict its instances creation class Node(object): def __init__(self, data, value): self.data = data self.value = value self.children = [] def addChild(self, child): self.children.append(child) def setValue(self, givenV): self.value = givenV try: result = cache[data] except KeyError: result = Node(data, value) cache[data] = result return result 对象的地方-我们仅应像使用此功能一样

    Node

    这将为我们提供与以前相同的输出。

进一步的改进

更改def primeQuery(n, first, second, values, queries): i = 0 while i < n - 1: f = get_or_create_node(first[i], values[first[i] - 1]) s = get_or_create_node(second[i], values[second[i] - 1]) f.addChild(s.data) print(f"First: {f.data} Value: {f.value} Children: {f.children}") i += 1 print(get_or_create_node(3).value)

如果我们关于value持久的假设被证明是错误的-如果通过了value更改,我们可以简单地添加它,例如:

  • 第一种方法:

    value
  • 第二种方法:将def get_or_create_node(data, value): try: # trying to access already created ``Node`` result = nodes[data] except KeyError: # no ``Node`` found, create it... result = Node(data, value) # ... and register nodes[data] = result # adding ``else``-clause else: result.setValue(value) return result 参数的默认值设置为value,并检查其是否指定为

    None

继承自def get_or_create_node(data, value=None, *, cache={}): class Node(object): def __init__(self, data, value): self.data = data self.value = value self.children = [] def addChild(self, child): self.children.append(child) def setValue(self, givenV): self.value = givenV try: result = cache[data] except KeyError: if value is None: # default value value = 0 result = Node(data, value) cache[data] = result else: if value is not None: result.setValue(value) return result

如果我们使用的是 Python 3 ,则无需将object指定为基类,则默认情况下将对其进行设置(请参见this thread),所以代替

object

我们可以简单地写

class Node(object):
    ...

使用class Node: ... 循环代替for

当我们有while循环和while对象时,我们不需要手动使用i循环和递增for,所以代替

range

我们可以写

i = 0
while i < n - 1:
    ...
    i += 1

我还认为这是一个错字,因为我们跳过了for i in range(n - 1): ... 等于i的情况,所以我们可以解决它:

n - 1

最后我们可以看到,当我们可以使用zip built-in并遍历for i in range(n): ... i first对时,second索引中就没有必要了像

这样的元素
list