Странный результат от выхода из в Python
У меня есть пример кода поиска в глубину в Python, как показано ниже.
def DFS_paths_recursive(self, start, end, path = None):
if path == None:
path = [start]
if start == end:
yield path
else:
unvisited = set(self._graph_dic[start]) - set(path)
for vertex in unvisited:
yield from self.DFS_paths_recursive(vertex, end, path+[vertex])
Но если я изменю код, как показано ниже, вывод будет странным. Я просто изменил путь перед рекурсивным вызовом в последней строке. В чем проблема?
def DFS_paths_recursive(self, start, end, path = None):
if path == None:
path = [start]
if start == end:
yield path
else:
unvisited = set(self._graph_dic[start]) - set(path)
for vertex in unvisited:
path.append(vertex)
yield from self.DFS_paths_recursive(vertex, end, path)
Например, для графа g = { "a" : ["d"], "b" : ["c"], "c" : ["b", "c", "d", "e"], "d" : ["a", "c", "e"], "e" : ["c"], "f" : ["g"], "g" : ["f"] }
Иногда вывод путей между "а" и "е" ['a', 'd', 'c', 'b', 'e'],['a', 'd', 'c', 'b', 'e', 'e']
и иногда вывод становится ['a', 'd', 'e']
,
1 ответ
Это не имеет ничего общего с yield from
, Когда вы делаете path.append(vertex)
мутируете оригинальную копию path
(что означает версию, которую ваш абонент передал вам, и версию, которую вы передаете рекурсивному вызову). Даже внутри функции она ведет себя по-разному, так как повторяется append
s означает, что каждый рекурсивный вызов обрабатывает все те же значения, что и последний плюс еще один, вместо фиксированной базы path
плюс одно дополнительное значение в каждом цикле.
дела path+[vertex]
создает новый list
перейти к рекурсивному вызову, предотвращая влияние мутаций на вашу собственную копию path
и только добавление одного нового value
на базу path
за каждый рекурсивный вызов без изменения базы path
,