Понимание вложенной доходности / возврата в Python - PullRequest
19 голосов
/ 28 июня 2011

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

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

Я хочу реорганизовать код (я упростил сценарий использования, но фактические вычисления могут быть сложными и более длинными. Пожалуйста, см. РЕДАКТИРОВАТЬ ниже). Исходя из моего понимания, это то, что я должен сделать, чтобы сохранить функциональность неизменной:

(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)

РЕДАКТИРОВАТЬ : Комментарии указывают на то, что правильный ответ зависит от варианта использования. Я хочу добавить, что мой вариант использования заключается в разборе файла XML для извлечения полей и записи их в базу данных. Эта часть делегирована sub_function (). Я также задал этот вопрос для общего понимания использования вложенного выхода для рефакторинга кода.

1 Ответ

12 голосов
/ 28 июня 2011

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

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

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

...