创建新列表与改变现有列表之间的区别

时间:2016-03-09 23:46:23

标签: python graph shortest-path

我正在尝试计算图表中从节点start到另一个end的最短路径。我一直在阅读应用于列表的+运算符,将元素连接到前者的末尾,从而创建一个新列表作为结果。而使用.extend()不仅可以将元素添加到列表的末尾,还可以保留相同的列表实例。

我不明白为什么如果我使用path = path + [start]我的代码有效,而不是我使用path.extend(start)。我没有看到每次调用函数时都需要创建一个新列表,以便返回正确的结果。

先谢谢。

def shortest_path_edge_num(graph, start, end, path = None, shortest = None):
    if (graph or start or end) is None: return None
    if path is None: path = []
    if shortest is None: 
        shortest = []

    path = path + [start]
    # path.extend([start])
    # Base case:
    if start == end: return path

    for adj_node in graph[start]:
        if adj_node[0] not in path:
        new_path = shortest_path_edge_num(graph, adj_node[0], end, path, shortest)
            if new_path:
                if (not shortest) or (len(new_path) < len(shortest)):
                    shortest = new_path
    return shortest

# Main routine
graph = {
    'A' : [('B',5),('F',10)],
    'B' : [('A',5),('E',2),('C',4)],
    'C' : [('B',4),('D',11)],
    'D' : [('C',11),('E',7)],
    'E' : [('B',2),('D',7),('F',1)],
    'F' : [('A',10),('E',1)]
}

print shortest_path_edge_num(graph,'A','C')

>>> python graph.py
['A', 'B', 'C']
>>> # But when changing to path.extend([start])
>>> python graph.py
['A', 'B', 'E', 'D', 'C', 'F']

修改

使用+创建list的新实例,因此每次向path添加新元素时,以某种方式依赖的所有其他变量都不会更改。现在问题应该是我应该如何消除这种依赖?

2 个答案:

答案 0 :(得分:0)

path.extend()期待另一个序列作为其参数。与您所说的path + [start]相同,您需要说path.extend([start])。但是,更简单的方法是使用.append()path.append(start)Herelist上的文档。

答案 1 :(得分:0)

我不知道将操作应用于path会导致其他变量的修改,例如new_pathshortest。当我看到正在执行path.append(start)path.extend([start])时还将start添加到其他两个列表中时,我意识到在{{1}中递归调用函数时我不应该使用path而是使用new_path = shortest_path_edge_num(graph, adj_node[0], end, path, shortest)来发送列表的副本而不是引用。

所以最后我保留了行path[:]path.append(start)并在递归调用中修改了参数path.extend([start])。通过这样做,程序按预期返回最短路径。

感谢您的评论和答案。