Python 路径之间的差异=路径+;[节点1],路径+;=[node1]和path.append(node1)
我正试图找出两者之间的区别Python 路径之间的差异=路径+;[节点1],路径+;=[node1]和path.append(node1),python,dictionary,graph,path,set,Python,Dictionary,Graph,Path,Set,我正试图找出两者之间的区别 路径=路径+[节点1] 路径+=[节点1] path.append(节点1) 对于path=path+[node1],我得到的是正确的路径,但不是其他两个 def find_path(self, node1, node2, path = []): """ Finds any path from node1 to node2 which may not be the shortest """ path = path + [node1] if n
def find_path(self, node1, node2, path = []):
""" Finds any path from node1 to node2 which may not be the shortest """
path = path + [node1]
if node1 == node2:
return path
if node1 not in self._graph:
return None
for node in self._graph[node1]:
if node not in path:
new_path = self.find_path(node, node2, path)
if new_path:
return new_path
return None
使用可变默认参数时,需要非常小心。请看
行为差异的原因是
path = path + [node1]
创建新列表并将其绑定到名称路径
。其他两个备选方案修改绑定到path
的现有列表
正如链接问题所解释的,默认参数是在编译函数定义时创建的,而不是在调用函数时创建的。在递归函数中使用可变默认参数时,这一点尤其重要,因为这意味着默认参数不会在每次顶级递归调用时重置 如果您不想要使用可变默认参数所提供的“特殊”行为,可以执行以下操作:
def find_path(self, node1, node2, path=None):
if path is None:
path = []
# rest of code
如果None
是path
的有效参数,则需要使用其他一些哨兵,例如
sentinel = object()
def find_path(self, node1, node2, path=sentinel):
if path is sentinel:
path = []
# rest of code
下面是一个简短的演示,演示了可变默认参数的“特殊”行为。您可以看到
lst
记住了它以前的内容
def test(a, lst=[]):
lst += [a]
print(a, lst)
for i in range(5):
test(i)
输出
0 [0]
1 [0, 1]
2 [0, 1, 2]
3 [0, 1, 2, 3]
4 [0, 1, 2, 3, 4]
0 [0]
1 [1]
2 [2]
3 [3]
4 [4]
相反,使用lst=lst+[a]
,我们创建一个新列表,而不是附加到默认列表
def test(a, lst=[]):
lst = lst + [a]
print(a, lst)
for i in range(5):
test(i)
输出
0 [0]
1 [0, 1]
2 [0, 1, 2]
3 [0, 1, 2, 3]
4 [0, 1, 2, 3, 4]
0 [0]
1 [1]
2 [2]
3 [3]
4 [4]
节点是什么?您是否收到错误消息或错误结果?它们只是来自[('A','B'),('B','C'),('B','D'),('C','D'),('E','F'),('F','C')]的像'A'和'B'这样的字符。这很好地解释了这一点,非常感谢!因此,那里的路径是局部的,而另外两个路径是全局的,因为它们会影响以前的递归调用?@SandeepChowdary这并不完全是局部/全局问题。默认列表参数的行为类似于函数的静态变量,但如果您不知道其他语言中的静态变量,我想这种解释没有多大帮助。:)因此,我刚刚添加了两个示例,这两个示例应该可以清楚地说明发生了什么。顺便说一句,如果我的答案对你有帮助,请考虑它。@ SaDeTiCoudDaRe>只是用Python,如果使用一个易变的对象,比如<代码> [/C]>作为默认参数,它在程序的开始时被创建一次,然后一次又一次地重复使用。因此,后续调用将看到以前对其进行的任何修改。这是一个有争议的设计,因为它与大多数其他语言相反,最终成为python初学者(以及一些更有经验的开发人员)经常遇到的陷阱。感谢大家对它的解释如此之好!