Почему этот генератор (с использованием рекурсии) не дает интуитивно понятных результатов - PullRequest
0 голосов
/ 05 апреля 2019

Я написал простую функцию генератора, которая берет список, который может иметь подсписки, и пытается сгладить список:

, поэтому [1, [2, 3], 4, [5, [6, 7], 8]] должны дать 1,2,3,4,5,6,7,8

Если я просто хочу распечатать значения (не генератор), это выглядит так, и это работает:

#  Code A
def flatten_list_of_lists(my_list):
    for element in my_list:
        if isinstance(element, list):
            flatten_list_of_lists(element)
        else:
            print(element)

my_list = [1, [2, 3], 4, [5, [6, 7], 8]]
flatten_list_of_lists(my_list)

И это печатает 1,2,3,4,5,6,7,8, как и ожидалось

Однако, когда я изменяю код на это:

#  Code B
def flatten_list_of_lists(my_list):
    for element in my_list:
        if isinstance(element, list):
            flatten_list_of_lists(element)
        else:
            yield element

for i in flatten_list_of_lists(my_list):
    print(i)

, который просто переключает печать на урожай, программа просто печатает 1,4.

Я вставлю код ниже, который на самом деле работает. Но мне интересно, почему предыдущий код не работает? Если код А «печатает» цифры правильно, почему код Б не «правильно» выводит цифры?

Похоже, у меня есть фундаментальное недопонимание того, как генераторы работают с рекурсией.

Этот код действительно работает:

#  Code C
def flatten_list_of_lists_v2(my_list):
    for element in my_list:
        if isinstance(element, list):
            for sub_element in flatten_list_of_lists_v2(element):
                yield sub_element
        else:
            yield element

l = []
for element in flatten_list_of_lists_v2(my_list):
    print(element)

И это распечатывает 1,2,3,4,5,6,7,8

Просто небольшой фон, я только что закончил смотреть это видео: https://www.youtube.com/watch?v=LelQTPiH3f4

и там он объясняет, когда вы проектируете свои генераторы, просто поместите отпечаток, который вы хотите получить, и посмотрите, получите ли вы правильные результаты, а затем просто переключите печать на выход. Поэтому я думаю, что его совет не работает при любых обстоятельствах, я просто хочу понять, почему.

1 Ответ

6 голосов
/ 05 апреля 2019

Простая ошибка -

def flatten_list_of_lists(my_list):
    for element in my_list:
        if isinstance(element, list):
            # add yield from
            yield from flatten_list_of_lists(element)
        else:
            # yield, not print
            yield element

my_list =  [1, [2, 3], 4, [5, [6, 7], 8]]

for e in flatten_list_of_lists(my_list):
  print(e)

Вывод

1
2
3
4
5
6
7
8
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...