Идиоматический Python для нетривиального понимания списка

Выполнение простого преобразования над итерируемым в Python идиоматически достигается с помощью понимания списка:

y = [f(arg) for arg in args]

где f это простое утверждение или функционал map если f является именованной функцией:

y = map(f, args)

Гвидо одобряет списки map(lambda x:..., args)и на самом деле перечислить понимание использования map или же filter на всех.

Однако мне не ясно, как я должен подходить к проблемам, которые:

  • изменить каждый элемент в итерации,
  • нетривиальным образом,
  • используя дискретную часть логики (может быть функцией),
  • это никуда не годится

Какой самый идиоматический способ решения этого типа проблемы? Некоторые вещи, которые я видел и пробовал в проектах Python, над которыми я работал:

Предобъявление и петля

Очевидный способ - предварительно объявить результат и цикл:

def transform(...):

    ...

    y = []
    for arg in args:
        first_statement
        second_statement
        ...
        y.append(statement)

Комментарии:

  • (про) легко следовать логике
  • (con) логика не ограничена (утечка абстракции)
  • (con) логика не явная (откуда вы знаете, что это карта без проверки того, как работают все ветви в цикле?)
  • (con) излишне предварительно объявляет переменную бесполезным способом (y ДОЛЖЕН быть такой же длины, как args)

Вложенная функция

Другой вариант - заключить логику во вложенную функцию, а затем вызвать ее, используя карту или списки:

def transform(...):

    ...

    def anonymous(arg):
        first_statement
        second_statement
        ...
        return statement

    y = map(anonymous, args)
    # y = [anonymous(arg) for arg in args]

Комментарии:

  • (Pro) Инкапсулирует логику
  • (Pro) Может получить доступ к внешней области видимости
  • (Pro) Невозможно изменить внешнюю область видимости (явно об отсутствии побочных эффектов)
  • (Con) Внутренняя функция переопределяется каждый раз, когда она вызывается
  • (Con) Внутренняя функция не имеет реального имени (должна быть анонимной в области видимости карты)

Внешняя функция

Перемещение внутренней функции во внешнюю область решает некоторые из этих проблем, но вводит больше:

def _anonymous(arg):
    first_statement
    second_statement
    ...
    return statement

def transform(...):

    ...

    y = map(_anonymous, args)

Комментарии:

  • (Pro): функция компилируется один раз в разбор
  • (Con): функция слишком далека от call-сайта для небольшого кусочка логики (вызывает ненужное переключение контекста для программиста)
  • (Con): функция не имеет доступа к внешней области видимости. Любые требования должны быть соблюдены (предотвращение использования map) или же partialроскопию

Резюме

Я в конфликте. Как вы решаете проблемы, когда вам нужно сделать нетривиальную одноразовую карту?

0 ответов

Другие вопросы по тегам