使用默认参数传递的列表被视为元组

时间:2015-12-23 21:16:34

标签: python list tuples

我试图调用此函数(只有第一行很重要):

def find_path(graph, start, end, path=[]):
    path = path + [start]
    if start == end:
        return path
    if not graph.has_key(start):
        return None
    for node in graph[start]:
        if node not in path:
            newpath = find_path(graph, node, end, path)
            if newpath: return newpath
    return None
像这样:

find_path(self.neighbors, (4,4), (0,4))

但我总是得到这个错误:

    path = path + [start]
TypeError: can only concatenate tuple (not "list") to tuple

我知道我无法更改元组,但我认为path是一个列表,当我检查它的类型时它会说元组,为什么会这样?您有什么建议来解决它?感谢

2 个答案:

答案 0 :(得分:3)

正如评论中所证实的,此代码的上下文如下所示:

class SomeClass:

    ...
    def find_path(graph, start, end, path=[]):
        ...

在你调用它的情况下,它会通过

find_path(graph=self, start=self.neighbors, end=(4,4), path=(0,4))

您需要使用签名

定义该方法
def find_path(self, graph, start, end, path=[])

关于可变默认参数的说明:当您决定使用它们时,请非常小心。它适用于这种情况,因为您要做的第一件事是使用path在方法范围内重新定义path = path + [start],但如果您的第一行是相同的path.append(start),您的方法将会非常难以调试。

默认参数的作用域与它们所属的函数的作用级别相同,因此,对于该函数的每个调用,都会更改它。因为那"陷阱,"一个常见的习语是:

def find_path(..., path=None):
    if path is None:
        path = []

或(等效但不太常见)

path = [] if path is None else path

答案 1 :(得分:0)

您需要查看作为“path”的参数传递的内容。我怀疑你的代码以某种方式将其作为一个元组。

>>> (4,4) + []
Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    (4,4) + []
TypeError: can only concatenate tuple (not "list") to tuple
>>> [] + (4,4)
Traceback (most recent call last):
  File "<pyshell#14>", line 1, in <module>
    [] + (4,4)
TypeError: can only concatenate list (not "tuple") to list

你得到的堆栈跟踪对应于第一种情况,其中“path”是一个元组,[start]是一个包含元组的列表。