简体   繁体   English

这两个python代码有什么区别? 为什么结果不同?

[英]what's the difference between these 2 python codes? why different results?

I'm writing a dfs code like below: 我正在编写如下的dfs代码:

def dfs(self, graph, node, path):
    if node==len(graph)-1:
        self.res.append(path)
    else:
        for i in graph[node]:
            path.append(i)
            self.dfs(graph, i, path)
            print(path.pop())

but got undesired result, while I changed the for loop code in dfs to: 但是得到了不希望的结果,而我将dfs中的for循环代码更改为:

self.dfs(graph, i, path+[i])

the result is what I want. 结果就是我想要的。 But I could not figure out what's the difference of these 2 piece codes. 但是我不知道这两个代码有什么区别。 Thanks 谢谢

Algorithm-wise, I need more information about how you represent the graph to give more insight. 在算法方面,我需要有关如何表示图形的更多信息,以提供更多见解。 But code-wise, the difference is caused by the fact that List in Python is mutable . 但是在代码方面,差异是由于Python中的List是可变的这一事实引起的。 That means in your original code, when you pop the path list, the entry in the res will change accordingly. 这意味着在您的原始代码中,当您pop path列表时, res的条目将相应更改。 Check this by the following. 通过以下检查。

a = [1,2,3]
b = []

b.append(a)  # b = [[1,2,3]]
a.pop()      # now b = [[1,2]]

But when you change the argument to path + [i] , a new List is constructed, ie the path inside the next recursive call of dfs is decoupled from that in the previous one. 但是,当您将参数更改为path + [i] ,将构造一个新的List,即,下一个dfs递归调用中的path与上一个中的path解耦。 Check this by the following. 通过以下检查。

a = [1,2]
b = []

b.append(a+[3])  # b = [[1,2,3]]
a.pop()          
# b is still [[1,2,3]], because the expression a + [3] will be evaluated to another List

Te original version mutates path in each iteration of each recursion. 原始版本会在每次递归的每次迭代中更改路径。 The second version just makes a copy and adds an extra element. 第二个版本只是复制并添加了一个额外的元素。 This copy is not bound to a name, it just get passed to the next level of recursion. 此副本未绑定到名称,它只是传递到下一级递归。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM