#python #generator #depth-first-search
#python #генератор #поиск в глубину
Вопрос:
Я был бы действительно признателен за вашу помощь. Я изучаю пути к DFS и понимаю код, но чего я не понимаю, так это последней строки. Почему я не могу просто вызвать функцию как dfs_paths(graph, ‘A’, ‘F’), а не list (dfs_paths(graph, ‘A’, ‘F’)), чтобы приведенный ниже код работал? Спасибо.
graph = {'A': set(['B', 'C']),
'B': set(['A', 'D', 'E']),
'C': set(['A', 'F']),
'D': set(['B']),
'E': set(['B', 'F']),
'F': set(['C', 'E'])}
def dfs_paths(graph, start, goal):
stack = [(start, [start])]
while stack:
(vertex, path) = stack.pop()
for next in graph[vertex] - set(path):
if next == goal:
yield path [next]
else:
stack.append((next, path [next]))
dfs_paths(graph, 'A', 'F')
Ответ №1:
Потому что dfs_paths
это не обычная функция; это функция генератора. Когда вы запускаете функцию, она возвращает только генератор и фактически не выполняет какой-либо код в теле, пока вы не начнете перебирать возвращаемое значение. Эта итерация может быть явной с помощью for
цикла:
for path in dfs_paths(graph, 'A', 'F'):
...
или неявный через функцию типа list
, которая использует итератор:
paths = list(dfs_paths(graph, 'A', 'F'))
Ответ №2:
Это оператор yield в функции.
Методы с yield в них являются генераторами. Генераторы возвращают итератор при вызове. Если вы хотите получить полное возвращаемое значение (весь путь), вы должны завершить итерацию по итератору. Отсюда необходимость в list()
— который неявно выполняет итерацию по итератору, предоставляя вам весь путь.