Лутц М. - Изучаем Python (1077325), страница 96
Текст из файла (страница 96)
Сделать это можно с помощью встроенной функции арр1у и специального синтаксиса вызова в языке Ру1Ьоп. о К моменту написания этих строк в версии Ру(Ьоп 2.5 можно исру„, пользовать и Функцию арр1у, и специальный синтаксис вызова, описываемые в этом разделе, но вполне вероятно, что в Руа)гоп 3.0 функция арр1у исчезнет. Если для вас желательно, чтобы ваш программный код сохранил свою работоспособность в будущем, используйте специальный синтаксис вызова, а не функцию арр1у. Встроенная функция арр1у Для обеспечения динамичности сгенерированные функции можно вызывать, передавая их в качестве аргументов функции арр1у вместе с кортежем аргументов, которые должны быть переданы этой функции: »> Сет попс(х, у, г); гетогп х + у + а »> арр1у(топо, (2, 3, 4)) 9 »> Г 1авзав х, у, гк х+ у+ в »> арр1у(Г, (2, 3, 4)) 9 Функция арр1у просто вызывает функцию, переданную ей в первом аргументе, и сопоставляет полученный кортеж аргументов с аргументами, которые ожидает получить функция.
Так как список аргументов передается в виде кортежа (т. е. в виде структуры данных), программа может создавать его во время выполнения.' Истинная мощь функции арр1у заключается в том, что ей не требуется знать, сколько аргументов принимает вызываемая ею функция. Например, можно с помощью условной инструкции (г организовать выбор из множества функций и списков аргументов и затем передавать их функции арр1у для вызова: (Г <тевт>: аст!оп, агдв = Гспс1, (1,) е1ве; аст(оп, агдв = Гипс2, (1, 2, 3) Будьте внимательны, не путайте функцию арр1у с функцией вар, которая описывается в следующем разделе.
Функция арр1у вызывает функцию, полученную в аргументе, всего один раз, в то время как аар вызывает функцию несколько раз, по одному разу для каждого элемента последовательности. 44а арр1у(аст!оп, вгдз) В общем случае функцию арр1у удобно использовать, когда заранее нельзя определить список аргументов. Например, когда пользователь выбирает произвольную функцию пользовательского интерфейса, может оказаться невозможным жестко определить вызов функции в сценарии. Чтобы решить эту проблему, можно просто создать список аргументов в виде кортежа и вызвать функцию косвенно, с помощью арр1у: Передача аргументов по ключу Функция зрр1у поддерживает третий необязательный аргумент, в ко- тором можно указать словарь, содержащий аргументы, передаваемые функции по ключу: »> Овт вспо( агцз, ° *Киагдв): рг1пт вгдв, Киагцз »> вспо( 1, 2, а 3, Ь=4) (1, 2) ('а': 3, 'Ь': 4) Эта возможность позволяет конструировать во время выполнения спи- ски позиционных аргументов и аргументов передаваемых по ключу: >» рагдв = (1, 2) »> Катца = ('а".3, 'Ь':4) »> арр1у(вспо, рагцв, Катца) (1, 2) ('в'; 3, 'Ь': 4) арр!у-подобный синтаксис вызова Тот же самый эффект, что дает функция арр1у, в языке РуЬ)топ можно получить с использованием специального синтаксиса вызова.
Этот синтаксис отражает синтаксис передачи произвольного числа аргументов в заголовке инструкции бе(, с которым мы познакомились в главе 16. Например, предположим, что в этом примере используются имена с присвоенными им значениями из примера выше: Этот специальный синтаксис вызова является более новым, чем функция арр1у, и, в общем, более предпочтительным.
Он не дает каких-ли- »> агдв = (2,3) + (4 ) »> агдв (2, 3, 4) »> арр1у(тцпс, агдз) 9 >» арр1у(тцпс, агдз) 9 »> Гцпс(*агре) 9 »> вспо( рагцв, ° *Катца) (1, 2) ('а': 3, 'Ь''. 4) Глаза 17. Расширенные возможности функций д традиционней способ: кортеи д новмй, ерр)у-псдобний синтаксис д Словари с ключами такие допустими Отображение функций на последовательности; гпар 449 »> есво(0, регрв, Хвгдв) я Обыяный, Гцр1е, * Шсттопвгу (О, 1, 2) ( е'. 3, 'Ь'; 4) Отображение функций на последовательности: тар Одна из наиболее часто встречающихся задач, которые решаются в программах, состоит в применении некоторой операции к каждому элементу в списке или в другой последовательности и сборе полученных результатов.
Например, обновление всех счетчиков в списке может быть выполнено с помощью простого цикла 10 г: »> сооптегв [1, 2, 3, 4] »> »> србвтеб = [] »> тот х 1п соцптегв; црбвтеб.вррепб(х + 10) я Прибввить 10 к квидону злененту »> црбетвб [11, 12, 13, 14] Но, так как такие операции встречаются достаточно часто, язык Ру- 1]топ предоставляет встроенную функцию, которая выполняет большую часть этой работы.
Функция ввр применяет указанную функцию к каждому элементу последовательности и возвращает список, содержащий результаты всех вызовов функции. Например: »> бег 1пс(х); гетсгп х + 10 з функция, каторвя долина быть вызвана »> вер(1пс, соцптегв) [ 1 1, 12, 13, 14 ] я Сбор результатов Функция вар была представлена в главе 13, как средство одновременного обхода сразу нескольких последовательностей в цикле. Как вы наверняка помните, в той главе вместо функции мы передавали объект йопе, чтобы выполнить попарное объединение элементов последовательностей. Ниже приводится более полезный пример, где используется настоящая функция, применяемая ко всем элементам списка,— функция вар вызывает функцию 1 по для каждого элемента списка и собирает полученные результаты в новый список.
Функция ввр ожидает получить в первом аргументе функцию, поэтому здесь часто можно встретить 1ввсбв-выражения: »> ввр((1ввЬбв х: х + 3), соцптегв) в Вырвиение-функция [4,5 0,7] бо очевидных преимуществ перед явным вызовом арр1у, кроме соответствия заголовку инструкции бе( и необходимости ввода меньшего числа символов.
Однако новый альтернативный синтаксис вызова позволяет передавать дополнительные аргументы и является более универсальным: Глава 17. Расширенные возможности функций В данном случае функция прибавляет число 3 к каждому элементу списка соэпте гэ, а так как эта функция нигде в другом месте больше не используется, она оформлена в виде 1эесзэ-выражения.
Такой вариант использования функции еар представляет собой эквивалент цикла Гог, поэтому такую утилиту в общем виде можно представить так: »> се( еуеар(тэсс, зес): гез = [! Гсг х 1п зес: гез.аррепо(типо(х)) гетсгп гез »> еар(1пс, [1, 2, 3!) [11, 12, 13! »> еуеар(1пс, [1, 2, 3)) [11, 12, 13! »> ров(3, 4) 81 »> еар(ров, [1, 2, 3), [2, 3, 4!) Ф 1 ° *2, 2.*3, Э* ° 4 [1, 8, 81) Здесь функция рок при каждом вызове принимает от функции еар два аргумента — по одному из каждой последовательности.
Мы могли реализовать свою собственную функцию, имитирующую это действие, но вполне очевидно, что в этом нет никакой необходимости, так как имеется высокопроизводительная встроенная функция. (':) Этот вызов функции шар напоминает генераторы списков, которые рассматривались в главе 13 и с которыми мы встретимся еще раз далее в этой главе. Основное отличие состоит в том, что еар применяет к каждому элементу последовательности не произвольное выражение, а функцию. Вследствие этого ограничения она обладает меньшей гибкостью.
Однако современная реализация еэр в некоторых случаях обладает более высокой производительностью, чем генераторы списков (например, когда отображается встроенная функция), и использовать ее проще. Благодаря этому функция еэр скорее всего останется доступной в версии Рутйоп 3.0. Однако в недавнем описании Русйоп 3.0 предлагалось убрать из встроенного пространств имен (и, возможно, перенести в модули) эту функцию, а также функции гесзсе и (111ег, которые будут рассматриваться в следующем разделе. Однако функция еар является встроенной функцией, поэтому она доступна всегда, всегда работает одним и тем же способом и обладает некоторыми преимуществами производительности (проще говоря — она выполняется быстрее, чем любой цикл Гог).
Кроме того, функция езр может использоваться в более сложных ситуациях, чем показано здесь. Например, в данном случае имеется несколько аргументов с последовательностями, а функция еар извлекает их параллельно и передает как отдельные аргументы в функцию: 451 Средства функционального программирования: (3!ег и гебосе В то время как функция вар может остаться в языке РуЬЬоп, функции гебзсе н г>11вг в версии 3.0 будут изъяты, отчасти потому, что онн избыточны н легко могут быть реализованы с помощью генераторов списков (функция т>11ег легко замещается оператором тг в генераторах списков), а отчасти из-за своей сложности (функция гвбзсе — одна нз самых сложных функций в языке н одна нз наименее понятных).
Впрочем, я не могу предсказывать будущее, поэтому за дополнительной информацией об этих и других изменениях обращайтесь к примечаниям к выпуску РусЬоп 3.0. Эти функции по-прежнему рассматриваются в данном издании книги потому, что онн входят в состав текущей версии РуЬЬоп, н почти наверняка будут встречаться в программном коде еще какое-то время. Средства функционального программирования: 6!1ег и гелосе Функция тиар — это простейший представитель класса встроенных функций в языке Ру(Ьоп, используемых в функциональном програмхтироаании, т. е.