Почему этот простой рекурсивный алгоритм обхода дерева терпит неудачу?

1

Я написал рекурсивный алгоритм для обхода вложенных итераторов в Python. Я не понимаю, почему он успешно распечатывает элементы, но не дает их в качестве генератора.

Пока мне удалось распечатать элементы:

tree = [[1,2],[3,[['abcde',['f']],'gh']]]

def traverse_printing(parent): 
     try: 
         for child in parent: 
              traverse(child) 
     except TypeError: 
         print(parent) 

>>> traverse_printing(tree)                                                                                                                                                                                    
1
2
3
a
b
c
...

Я изо всех сил пытаюсь превратить его в генератор.

def traverse(parent): 
     try: 
         for child in parent: 
              traverse(child) 
     except TypeError: 
         yield parent 

traverse(tree) настоящее время не работает. Результат:

>>> list(traverse(tree))                                                                                                                                                                              
[]

Ожидаемый результат будет [1,2,3,'a','b','c','d','e','f','g','h']

Почему это так? Большое спасибо

Теги:
generator
tree
nested
traversal

1 ответ

1

traverse возвращает объект-генератор. Таким образом, при вызове traverse вы должны перебрать возвращенный результат и получить каждое значение или использовать оператор yield from:

for child in parent: 
   yield from traverse(child) 

Однако ваше текущее решение завершается с ошибкой RecursionError: maximum recursion depth exceeded потому что вы перехватываете только повторение по целочисленному значению (которое вызывает TypeError). Цикл над строкой является допустимой операцией в Python, следовательно, бесконечные рекурсивные вызовы. Таким образом вам нужно будет проверить фактические типы parent:

def traverse(parent): 
  if isinstance(parent, str):
     yield from parent
  elif isinstance(parent, int):
     yield parent
  else: 
     for child in parent: 
        yield from traverse(child) 

list(traverse(tree))

Выход:

[1, 2, 3, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
  • 0
    Это было очень полезно! Чтобы сделать его простым и независимым от типа, я просто добавил еще одно предложение, except RecursionError: yield parent и это сработало как шарм. Спасибо

Ещё вопросы

Сообщество Overcoder
Наверх
Меню