为什么这个示例变量不递增(Python)?

wn9m85ua  于 2023-02-11  发布在  Python
关注(0)|答案(1)|浏览(134)

我已经实现了一个深度优先搜索算法,并使用一个名为“call-count”的示例变量,我试图跟踪代码内部执行了多少次递归/比较,即“searchDFS”运行了多少次。在“searchDFS”内部,call_count变量默认为第一次运行searchDFS时的示例变量,然后它被传递到每个递归中,所有其他的示例变量都工作正常,我可以很好地附加到顶级示例数组“final_path”,但是它拒绝递增call_count。
我做错了什么,还有更好的方法吗?
代码:

class Node:
    def __init__(self, id, connections):
        self.id = id
        self.connections = connections

class DFS:
    def __init__(self):
        self.visited = {}
        self.nodes = []
        self.final_path = []
        self.call_count = 0

    def searchDFS(self, nodes, target, current, call_count=None, final_path=None, visited=None):
        if(visited == None): visited = self.visited
        if(final_path == None): final_path = self.final_path
        if(call_count == None): call_count = self.call_count
        
        call_count +=1 # <<< to increment every time searchDFS is ran
        
        if current in visited.keys(): 
            print(f'already visited node {current}')
            return 0
             
        else:
            print(f'current -> {current}')
            visited[current] = 1

            if(current == target): 
                print('found!')
                final_path.append(current)
                return True
            
            if(nodes[current].connections):
                for node in nodes[current].connections:
                    if(self.searchDFS(nodes, target, node.id, call_count, final_path, visited)):
                        final_path.append(current)
                        if(current == 0): 
                            print(final_path[::-1])
                            print(f'call count: {call_count}') # not incrementing !!! :(
                        return True
            return False
    def setup_graph(self):
        for x in range(0, 5):
            self.nodes.append(Node(x, []))
        self.nodes[0].connections = [self.nodes[1], self.nodes[2]]
        self.nodes[1].connections = [self.nodes[0], self.nodes[3]]
        self.nodes[2].connections = [self.nodes[0], self.nodes[4]]
        self.nodes[3].connections = [self.nodes[1]]
        self.nodes[4].connections = [self.nodes[2]]

    def print_graph(self):
        for node in self.nodes:
                print(f"node id: {node.id}")
                print("children: ")
                for childs in node.connections:
                    print(childs.id)

    def main(self):
        print('main() init')
        self.setup_graph()
        self.print_graph()
        self.searchDFS(self.nodes, 4, 0)

if __name__ == "__main__":
    DFS().main()
xt0899hw

xt0899hw1#

通过@slothrop(in-depth explanation)解决
区别在于“重新绑定名称”与“改变值”
原语在Python中是不可变的--它们不能被改变,只能创建新的原语(并且变量名被重新绑定到新值):

x = 5
x = x + 1

上面的代码用新值6创建了一个新的内存块,然后x重新绑定到这个新值,这类似于C中指针的工作方式。
未赋值的值会被Python的垃圾收集器自动丢弃。保存“5”的内存单元将被清除,因为它不再被赋值给任何变量。
赋值语句从不复制数据,所以将一个变量赋值给另一个变量不会复制第一个变量,它只是给它“指示”去哪里找值。

x = 5 # creates a value 5, with 'x' pointing to it
y = x # y is now pointing/bound to that same value, 5, as well
x = x + 1 # a new value, 6, is created, and x is "bound" to it
print(x) # outputs 6
print(y) # outputs 5

“y”仍然“绑定/查看”原始的“5”。还有可变值,如Lists。Lists包含一个内置函数,可以附加到自身。

x = [1, 2]
y = x
x.append(3)
print(y) # outputs [1, 2, 3]

因为List是一个类,所以它可以有方法来原地改变,而不必像原语那样创建一个全新的值。
在我的代码中,当我赋值“call_count =self.call_count”时,我只将“call_count”的值指向示例变量“self.call_count”的相同值。递增“call_count”只会为 * 本地变量 *“call_count”赋值一个新值,而不会重新赋值原始的 * 示例变量 *“self.call_count”。要解决此问题,我只是创建了一个函数来更新示例的值,并在搜索函数中将一个变量绑定到该方法:

class DFS:
    def __init__(self):
        self.call_count = 0

    def increment_call_count(self):
        self.call_count += 1

    def searchDFS(self, counter=0, inc=None):
        if(inc == None): inc = self.increment_call_count # set once
        inc() # execute the function which "inc" is pointing at
        if(counter<5):
            self.searchDFS(counter + 1, inc)
        if(counter == 0): print(self.call_count) # prints 6 correctly

    def main(self):
        self.searchDFS()

if __name__ == "__main__":
    DFS().main()

由于inc只绑定到一个函数一次,因此inc的“值”永远不会改变,使用它只会运行同一个函数,该函数将原始示例的变量重新绑定到新值。

相关问题