Подтвердить что ты не робот

Понимание вложенной доходности/возврата в python

У меня есть функция в python, выход которой является генератором:

def main_function(x):
    r = get_range()
    for i in range(r):
        yield x+i

Я хочу реорганизовать код (я упростил вариант использования, но фактическое вычисление может быть сложным и дольше. См. ниже EDIT). Основываясь на моем понимании, это то, что я должен сделать, чтобы сохранить функциональность без изменений:

(a) Тот же интерфейс, что и исходный код

    def sub_function(x,r):
        for i in range(r):
            yield x+i    

    def main_function(x):
        r = get_range()
        return sub_function(x,r)

По сравнению с другими подходами, где:

(b) Это вернет генератор генератора (существуют ли какие-либо преимущества этого подхода?)

    def sub_function(x,r):
        for i in range(r):
            yield x+i    

    def main_function(x):
        r = get_range()
        yield sub_function(x,r)

(c) Это приведет к поражению цели генератора (это правильно?)

    def sub_function(x,r):
        return [x+i for i in range(r)]

    def main_function(x):
        r = get_range()
        for i in sub_function(x,r):
            yield(i)

EDIT. Комментарии указывают, что правильный ответ зависит от использования. Я хочу добавить, что мой пример использования - это разбор XML файла для извлечения полей и записи их в базу данных. Эта часть делегируется sub_function(). Я также задал этот вопрос для общего понимания использования вложенной доходности для кода рефакторинга.

4b9b3361

Ответ 1

Вы правы; исходный пример и а) делают то же самое, поскольку оба возвращают генератор.

b) отличается: он возвращает генератор, который дает один элемент (который является другим генератором). Чтобы использовать это, вам нужны две петли (одна над внешней и одна над внутренним генератором).

Нет никаких преимуществ как таковых, но иногда это может быть полезно для создания вложенных генераторов.

c) может быть хуже, но я уверен, что [x for x in y] фактически реализован как генератор. Так что это немного дороже, но не так много.