Как применить функцию ко всем элементам списка пайтон

  • автор:

Основы функционального программирования на Python

Этот пост служит для того, чтобы освежить в памяти, а некоторых познакомить с базовыми возможностями функционального программирования на языке Python, а также дополнением к моему предыдущему посту о конвейере данных. Материал поста разбит на 5 частей:

Принципы функционального программирования

Оператор lambda , функции map , filter , reduce и другие

Включение в последовательность

Рекомендации по ФП на языке Python

Принципы функционального программирования

Функциональное программирование представляет собой методику написания программного обеспечения, в центре внимания которой находятся функции. Функции могут присваиваться переменным, они могут передаваться в другие функции и порождать новые функции. Python имеет богатый и мощный арсенал инструментов, которые облегчают разработку функционально-ориентированных программ.

В последние годы почти все известные процедурные и объектно-ориентированные языки программирования стали поддерживать средства функционального программирования (ФП). И язык Python не исключение.

Когда говорят о ФП, прежде всего имеют в виду следующее:

Функции – это «граждане более высокого сорта», т.е., все, что можно делать с «данными», можно делать и с функциями (в том числе передача функции другой функции в качестве аргумента).

Использование рекурсии в качестве основной структуры контроля потока управления. В некоторых языках не существует иной конструкции цикла, кроме рекурсии.

Акцент на обработке последовательностей. Списки с рекурсивным обходом подсписков часто используются в качестве замены циклов.

«Чистые» функциональные языки избегают побочных эффектов. Это исключает присваивания, почти повсеместно распространенный в императивных языках подход, при котором за одной и той же переменной последовательно закрепляются разные значения для отслеживания состояния программы.

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

ФП акцентируется на том, что должно быть вычислено, а не как.

Функциональное программирование представляет собой методику написания программного обеспечения, в центре внимания которой находятся функции. В парадигме ФП объектами первого класса являются функции. Они обрабатываются таким же образом, что и любой другой примитивный тип данных, такой как строковый и числовой. Функции могут получать другие функции в виде аргументов и на выходе возвращать новые функции. Функции, имеющие такие признаки, называются функциями более высокого порядка из-за их высокой выразительной мощи. И вам непременно следует воспользоваться их чудесной выразительностью.

Программистам чаще приходится работать с последовательностями значений, такими как списки и кортежи, или же контейнерами, такими как словари и множества. Как правило, в файлах хранятся большие объемы текстовых или числовых данных, которые затем загружаются в программу в соответствующие структуры данных и обрабатываются. Python имеет богатый и мощный арсенал инструментов, которые облегчают их обработку в функциональном стиле.

Далее будут представлены несколько таких встроенных функций.

Оператор lambda, функции map, filter, reduce и другие

Прежде чем продолжить, сначала следует познакомиться с еще одним ключевым словом языка Python. Он позволяет определять еще один тип функций.

Оператор lambda

Помимо стандартного определения функции, которое состоит из заголовка функции с ключевым словом def и блока инструкций, в Python имеется возможность создавать короткие однострочные функции с использованием оператора lambda , которые называются лямбда-функциями. Вот общий формат определения лямбда-функции:

lambda список_аргументов: выражение

В данном формате список_аргументов – это список аргументов, отделенных запятой, и выражение – значение либо любая порция программного кода, которая в результате дает значение. Например, следующие два определения функций эквивалентны:

Но в отличие от стандартной функции, после определения лямбда-функции ее можно сразу же применить, к примеру, в интерактивном режиме:

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

Здесь в строке 1 определяется лямбда-функция и присваивается переменной, которая теперь ссылается на лямбда-функцию. В строке 2 она применяется с двумя аргументами. В строке 4 ссылка на эту функцию присваивается еще одной переменной, и затем пользуясь этой переменной данная функция вызывается еще раз. В строке 7 создается словарь, в котором в качестве значения задана ссылка на эту функцию, и затем, обратившись к этому значению по ключу, эта функция применяется в третий раз.

Нередко во время написания программы появляется необходимость преобразовать некую последовательность в другую. Для этих целей в Python имеется встроенная функция map.

Функция map

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

Встроенная в Python функция map – это функция более высокого порядка, которая предназначена для выполнения именно такой задачи. Она позволяет обрабатывать одну или несколько последовательностей с использованием заданной функции. Вот общий формат функции map :

В данном формате функция – это ссылка на стандартную функцию либо лямбда-функция, и последовательности – это одна или несколько отделенных запятыми итерируемых последовательностей, т.е. списки, кортежи, диапазоны или строковые данные.

В приведенном выше интерактивном сеансе в строках 1 и 2 двум переменным, seq и seq2, присваиваются две итерируемые последовательности. В строке 3 переменной result присваивается результат применения функции map, в которую в качестве аргументов были переданы ранее определенная лямбда-функция и две последовательности. Обратите внимание, что функция map возвращает объект-последовательность map, о чем говорит строка 5. Особенность объекта-последовательности map состоит в том он может предоставлять свои элементы, только когда они требуются, используя ленивые вычисления. Ленивые вычисления – это стратегия вычисления, согласно которой вычисления следует откладывать до тех пор, пока не понадобится их результат. Программистам часто приходится обрабатывать последовательности, состоящие из десятков тысяч и даже миллионов элементов. Хранить их в оперативной памяти, когда в определенный момент нужен всего один элемент, не имеет никакого смысла. Ленивые вычисления позволяют генерировать ленивые последовательности, которые при обращении к ним предоставляют следующий элемент последовательности. Чтобы показать ленивую последовательность, в данном случае результат работы примера, необходимо эту последовательность «вычислить». В строке 6 объект map вычисляется во время преобразования в список.

Функция filter

Функции более высокого порядка часто используются для фильтрации данных. Языки функционального программирования предлагают универсальную функцию filter , получающую набор элементов для фильтрации, и фильтрующую функцию, которая определяет, нужно ли исключить конкретный элемент из последовательности или нет. Встроенная в Python функция filter выполняет именно такую задачу. В результирующем списке будут только те значения, для которых значение функции для элемента последовательности истинно. Вот общий формат функции filter :

В данном формате предикативная_функция – это ссылка на стандартную функцию либо лямбда-функция, которая возвращает истину либо ложь, и последовательность – это итерируемая последовательность, т.е. список, кортеж, диапазон или строковые данные.

Например, ниже приведена однострочная функция is_even для определения четности числа:

Чтобы отфильтровать все числа последовательности и оставить только четные, применим функцию filter :

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

И снова, в обоих случаях функция filter возвращает ленивый объект-последовательность, который нужно вычислить, чтобы увидеть результат. В иной ситуации в программе может иметься процесс, который потребляет по одному элементу за один раз. В этом случае в него можно подавать по одному элементу, вызывая встроенную функцию next .

Примечание . Для предотвращения выхода за пределы ленивой последовательности необходимо отслеживать возникновение ошибки StopIteration. Например,

Функция reduce

Наконец, когда требуется обработать список значений таким образом, чтобы свести процесс к единственному результату, для этого используется функция reduce. Функция reduce имеется в модуле functools стандартной библиотеки, но здесь она будет приведена целиком, чтобы показать, как она работает:

Вот общий формат функции reduce :

reduce(функция, последовательность, инициализатор)

В данном формате функция – это ссылка на редуцирующую функцию; ею может быть стандартная функция либо лямбда-функция, последовательность – это итерируемая последовательность, т.е. список, кортеж, диапазон или строковые данные, и инициализатор – это параметрическая переменная, которая получает начальное значение для накопителя. Начальным значением может быть значение любого примитивного типа данных либо мутабельный объект – список, кортеж и т.д. Начальное значение инициирует накапливающую переменную, которая прежде чем она будет возвращена, будет обновляться редуцирующей функцией по каждому элементу в списке.

Переданная при вызове функция вызывается в цикле для каждого элемента последовательности. Например, функция reduce может применяться для суммирования числовых значений в списке. Например, вот так:

Вот еще один пример. Если sentences – это список предложений, и требуется подсчитать общее количество слов в этих предложениях, то можно написать, как показано в приведенном ниже интерактивном сеансе:

В лямбда-функции, на которую ссылается переменная wsum , строковый метод split разбивает предложение на список слов, функция len подсчитывает количество элементов в получившемся списке и прибавляет его в накапливающую переменную.

В чем преимущества функций более высокого порядка?

Они нередко состоят из одной строки.

Все важные компоненты итерации – объект-последовательность, операция и возвращаемое значение – находятся в одном месте.

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

Они представляются собой элементарные операции. Глядя на цикл for , приходится построчно отслеживать его логику. При этом в качестве опоры для создания своего понимания программного кода приходится отталкиваться от нескольких структурных закономерностей. Напротив, функции более высокого порядка одновременно являются строительными блоками, которые могут быть интегрированы в сложные алгоритмы, и элементами, которые читатель кода может мгновенно понять и резюмировать в своем уме. «Этот код преобразовывает каждый элемент в новую последовательность. Этот отбрасывает некоторые элементы. А этот объединяет оставшиеся элементы в единый результат».

Они имеют большое количество похожих функций, которые предоставляют возможности, которые служат дополнением к их основному поведению. Например, any , all или собственные их версии.

Приведем еще пару полезных функций.

Функция zip

Встроенная функция zip объединяет отдельные элементы из каждой последовательности в кортежи, т.е. она возвращает итерируемую последовательность, состоящую из кортежей. Вот общий формат функции zip :

В данном формате последовательность – это итерируемая последовательность, т.е. список, кортеж, диапазон или строковые данные. Функция zip возвращает ленивый объект-последовательность, который нужно вычислить, чтобы увидеть результат. Приведенный ниже интерактивный сеанс это демонстрирует:

В сочетании с оператором * эта функция используется для распаковки объединенной последовательности (в виде пар, троек и т.д.) в отдельные кортежи. Приведенный ниже интерактивный сеанс это демонстрирует:

Функция enumerate

Встроенная функция enumerate возвращает индекс элемента и сам элемент последовательности в качестве кортежа. Вот общий формат функции enumerate:

В данном формате последовательность – это итерируемая последовательность, т.е. список, кортеж, диапазон или строковые данные. Функция enumerate возвращает ленивый объект-последовательность, который нужно вычислить, чтобы увидеть результат.

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

В строке 2 применена функция list , которая преобразовывает ленивую последовательность в список. Функция enumerate также позволяет применять заданную функцию к каждому элементу последовательности с учетом индекса:

Функция convert в строке 1 переводит строковое значение второго элемента кортежа в верхний регистр и присоединяет к нему преобразованное в строковый тип значение первого элемента. Здесь tup – это кортеж, в котором tup[0] – это индекс элемента, и tup[1] – строковое значение элемента.

Включение в последовательность

Операции отображения и фильтрации встречаются так часто, что во многих языках программирования предлагаются способы написания этих выражений в более простых формах. Например, в языке Python возвести список чисел в квадрат можно следующим образом:

Python поддерживает концепцию под названием «включение в последовательность» (от англ. comprehension, в информатике эта операция так же называется описанием последовательности), которая суть изящный способ преобразования одной последовательности в другую. Во время этого процесса элементы могут быть условно включены и преобразованы заданной функцией. Вот один из вариантов общего формата операции включения в список:

[выражение for переменная in список if выражение2]

В данном общем формате выражение – это выражение или функция с участием переменной, которые возвращают значение, переменная – это элемент последовательности, список – это обрабатываемый список, и выражение2 – это логическое выражение или предикативная функция с участием переменной. Чтобы все стало понятно, приведем простой пример возведения список в квадрат без условия:

Приведенное выше включение в список эквивалентно следующему ниже фрагменту программного кода:

Такая форма записи называется синтаксическим сахаром, т.е. добавленная синтаксическая конструкция, позволяющая записывать выражения в более простых и кратких формах. Неплохой аспект конструкций включения в последовательность состоит еще и в том, что они легко читаются на обычном языке, благодаря чему программный код становится чрезвычайно понятным.

В конструкции включения в последовательность используется математическая запись построения последовательности. Такая запись в теории множеств и логике называется определением интенсионала множества и описывает множество путем определения условия, которое должно выполняться для всех его членов. В сущности, в терминах этих областей науки, выполняя данную операцию в Python, мы «описываем интенсионал» соответственно списка, словаря, множества и итерируемой последовательности. Ниже приведены примеры описания интенсионала соответственно списка, словаря, множества и итерируемой последовательности.

Таблица 1. Формы описания интенсионала

Выражение

Описание

[x*x for x in numbers]

set(x*x for x in numbers)

(x*x for x in numbers)

Описание последовательности. Такая форма записи создает генератор последовательности. Генератор – это объект, который можно последовательно обойти (обычно при помощи инструкции for ), но чьи значения предоставляются только тогда, когда они требуются, используя ленивое вычисление.

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

Таким образом, примеры из разделов о функциях map и filter легко можно переписать с использованием включения в последовательность. Например, в строке 3 приведенного ниже интерактивного сеанса вместо функции map применена операция включения в список:

Обратите внимание на квадратные скобки в определении – они сигнализируют, что в результате этой операции будет создан список. Также стоит обратить внимание, что при использовании в данной конструкции нескольких последовательностей применяется встроенная функция zip , которая в данном случае объединяет соответствующие элементы каждой последовательности в двухэлементные кортежи. (Если бы последовательностей было три, то они объединялись бы в кортежи из трех элементов и т.д.)

Включение в список применено и в приведенном ниже примере вместо функции filter :

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

Замыкание

Функции более высокого порядка не только получают функции на входе, но и могут порождать новые функции на выходе. Они даже в состоянии запоминать ссылку на значение в функции, которую они генерируют. Это называется замыканием. Функция, имеющая замыкание, может «запоминать» и получать доступ к среде вложенных в нее значений.

Используя замыкания, можно разделить исполнение функции со многими аргументами на большее количество шагов. Эта операция называется каррированием и обязана своим названием Хаскелю Каррингу. Каррирование – это преобразование функции многих аргументов в функцию, берущую свои аргументы по одному. Например, предположим, ваш программный код имеет приведенную ниже стандартную функцию adder :

Чтобы сделать ее каррированной, она должна быть переписана следующим образом:

Это же самое можно выразить при помощи лямбда-функций:

Обратите внимание, что в последнем примере используются две вложенные лямбда-функции, каждая из которых принимает всего один аргумент. В такой записи функция adder теперь может вызываться всего с одним аргументом. Выражение adder(3) возвращает не число, а новую, каррированную функцию. Во время вызова функции adder со значением 3 в качестве первого аргумента ссылка на значение 3 запоминается в каррированной функции. А дальше происходит следующее:

В приведенном выше примере каррированная функция adder(3) присваивается переменной sum_three, которая теперь на нее ссылается. Если вызвать функцию sum_three , передав ей второй аргумент, то она вернет результат сложения двух аргументов 3 и 1.

Замыкания также используются для генерирования набора связанных функций по шаблону. Использование шаблона функции помогает делать программный код более читаемым и избегать дублирования. Давайте посмотрим на приведенный ниже пример:

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

Отметим, что функции square и cube сохраняют значение переменной base . Эта переменная существовала только в среде power_generator , несмотря на то, что эти возвращенные функции абсолютно независимы от функции power_generator . Напомним еще раз: замыкание – это функция, которая имеет доступ к некоторым переменным за пределами своей собственной среды.

Замыкания могут также использоваться для управления внутренним состоянием функции. Давайте предположим, что требуется функция, которая накапливает сумму всех чисел, которые ей предоставляются. Один из способов это сделать состоит в использовании глобальной переменной:

Как мы убедились, применение глобальных переменных следует избегать, потому что они загрязняют пространство имен программы. Более чистый подход состоит в использовании замыкания, чтобы включить ссылку на накапливающую переменную:

Такой подход позволяет создавать несколько счетчиков без применения глобальных переменных. Обратите внимание, что в этом примере использовано ключевое слово nonlocal , которое объявляет, что переменная n не является локальной для вложенной функции fn. В приведенном ниже интерактивном сеансе показано, как это работает:

Некоторые языки программирования строго функциональны; весь код эквивалентен чистым математическим функциям. Эти языки заходят настолько далеко, что являются вневременными, причем порядок операторов в программном коде не вмешивается в поведение кода. В этих языках все присвоенные переменным значения являются немутируемыми. Такое присваивание называется однократным. Поскольку состояние программы отсутствует, то и нет момента времени, когда переменная может измениться. Вычисления в строгой функциональной парадигме просто сводятся к вычислению функций и сопоставлению с шаблонами.

Рекомендации по ФП на языке Python

Понятие ФП несколько различается по строгости формулировки. Одни понимают применение только функций, немутируемость и наведение мостов с периферией (вводом-выводом). Другие определяют ФП строже и наряду с немутируемостью говорят о применении только чистых функций. Но в любом случае программирование в функциональном стиле не тождественно функциональному программированию. Применение первоклассных функций, лямбд, итераторов, включений, каррирования и сопоставления с шаблонами вовсе не означает немутируемость и чистые функции.

Программирование в функциональном стиле не тождественно функциональному программированию.

Что делает функции нечистыми?

Глобальные мутации, т.е. внесение изменений в глобальное состояние,

Недетерминированность функций, т.е. которые для одинаковых входных значений могут возвращать разные результаты, и

Пример глобальной мутации:

Пример операции ввода-вывода:

Из чистых функций вытекает ссылочная (референциальная) прозрачность. Говорят, что программа или математическое выражение ссылочно прозрачны, если любое подвыражение можно заменить его значением, и это не приведет к изменению значения целого, т. е. скрытые побочные эффекты отсутствуют. Математические рассуждения, преобразования и доказательства корректности могут быть справедливыми только для выражений, обладающих этим свойством. А программы, написанные на обычных императивных языках, не являются ссылочно прозрачными, так как присваивание значений глобальным переменным, в некоторых случаях и локальным, вызывает скрытые побочные эффекты.

Ссылочная прозрачность (1) улучшает тестопригодность программ, т.е. поведение подпрограмм не зависит от контекста, повторный запуск приложения дает одинаковый результаты как следствие отсутствия мутаций, (2) обеспечивается модульность, т.е. поведение функций не зависит от контекста, и чистые функции можно легко составлять в композиции, строя новые формы поведений, (3) упрощает обеспечение конкурентности из-за отсутствия необходимости в синхронизации, т.к. отсутствие совместных мутируемых данных делает синхронизацию ненужной.

Однако, ФП имеет свои недостатки, такие как новизна парадигмы и иногда ухудшение производительности программ. Но в нашем случае главный недостаток состоит в том, что язык Python, как таковой, не является языком функционального программирования. Например, в нем нет библиотеки по работе с неизменяемыми структурами данных и оптимизации стека под хвостовую рекурсию. Однако эффективное функциональное программирование на Python вполне возможно.

Эффективное функциональное программирование на Python вполне возможно.

В отличие от объектно-ориентированного программирования, которое строит сложные формы поведения с помощью наследования, ФП опирается на композицию функций. Этот принцип перекликается с философией Unix, состоящей из 2 правил:

Правило композиции — строить программы так, чтобы иметь возможность легко их соединять с другими программами.

Правило модульности — писать простые части, которые можно соединять чистыми интерфейсами.

Указанные выше два простых правила делают ненужными архитектурные шаблоны и принципы ООП, заменяя их функциями! А что, спросите вы, и классы тоже? В Python использование классов не противоречит ФП, если в них отсутствует мутирующие интерфейсы.

Пример класса с мутирующим интерфейсом:

Пример класса без мутирующего интерфейса:

Но лучше использовать замороженные dataclasses и копирование, где необходимо. Иными словами, все классы должны быть замороженными dataclasses.

При всем при этом dataclasses могут быть вполне себе умными!

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

Как вариант, использовать декларативные включения в список, включения в словарь и включения в множество в качестве замены функций map и filter , хотя эта рекомендация является факультативной.

И применять архитектурный шаблон «немутируемое ядро — мутируемая оболочка» (aka «функциональное ядро — императивная оболочка»), который позволяет выносить мутацию во вне и производить ее на границах приложения.

Выводы

Функциональное программирование сконцентрировано вокруг немутируемости и чистых функций. Чистота позволяет производить код, который более пригоден для тестирования, функциональных композиций и управления в конкурентной обстановке. Следует избегать мутирующих интерфейсов и стремиться использовать замороженные dataclasses, сторонние библиотеки наподобие toolz и включения, при этом оставаясь идиоматичным.

Данный пост служит дополнением к моему предыдущему посту о конвейере данных. Приведенный выше материал был опубликован в качестве авторского в переводе книги Starting Out with Python и дополнен материалами Энтони Хвона.

Как применить функцию к каждому подсписку списка в python?

И у меня есть функция, скажем, я хочу применить функцию F к каждому подсписку функции F , которая может вычислить некоторую оценку по двум спискам. Как применить эту функцию F к каждому списку list_of_lists и вернуть каждый счет в новый список, например так:

Я попытался с помощью функции map :

5 ответов

Для этого вы можете использовать встроенный map .

Поэтому, если вы хотите применить функцию len , вы должны сделать:

В Python3 приведенное выше возвращает итератор карты, поэтому вам потребуется явный вызов list :

Если вы хотите написать какой-то код для этого, который должен быть совместим как в Python2, так и в Python3, то лучше всего использовать списочные понимания. Что-то вроде:

Будет работать в Python 2 и 3 без каких-либо изменений.

Однако, если ваш входной список list_of_lists огромен, использование map в Python3 имело бы больше смысла, потому что итератор будет намного быстрее.

То, что работает в произвольно вложенных списках, например [[1,2], [[5]], [7, [8, [9,11]]]]:

Вот пример запуска этого:

И вот как сделать то же самое только на выбранных уровнях:

Здесь можно сделать некоторые оптимизации, избегая передачи f и levels вокруг (делая рекурсивную функцию внутренней функцией в оболочке, так что он может использовать f и levels из внешней области видимости), но это незначительно. (Обратите внимание, что это Python 2, для Python 3 вам нужно заменить map чем-то другим).

Для более общего ввода, следующее может помочь:

Так что теперь также следующий вид работ:

(все немного переписывается, так как map() всегда создает списки . )

Который будет перебирать список list_of_lists, вызывать F с каждым подсписком в качестве аргумента, а затем генерировать список результатов.

Если вы хотите использовать подсписки в качестве всех аргументов F , вы можете сделать это немного по-другому, так как

Карта твой друг! map принимает функцию и итерацию (например, список) и применяет функцию к каждому элементу списка.

Если вы хотите сделать более детальный расчет для элементов подсписка, вы можете вложить карту:

Другой возможный подход (также из функционального программирования) — это списки. Понимание списка — это способ построения списка из итерируемого в Python. Синтаксис: [element for element in iterable] . Любое вычисление может быть сделано на элементе, поэтому

Означает, что результирующий список будет списком элементов, где каждый элемент является результатом функции f. Как и карта, понимание списка может быть далее вложено, что приводит к применению функции вложенного элемента.

Вы можете использовать понимание списка, как это

Примечание: . Хотя понимание списка выглядит как способ применения функции ко всем элементам, его основное назначение — создать новый список. Итак, если вы не хотите создавать новый список, просто выполните итерацию с циклом for и вызовите функцию.

Кроме того, вы можете использовать функцию map в Python 2.7, чтобы применить функцию ко всем элементам и создать список. Например,

Но map возвращает объект итератора карты в Python 3 .Икс. Итак, вам нужно явно преобразовать это в список, как это

Возможно, вы захотите прочитать о том, что думает Гвидо о map в этом посте..

По сути, map чаще требует от вас создания новой функции (в основном люди создают функцию lambda ). Но во многих случаях понимание списка избегает этого.

Топ-15 лайфхаков для работы с Python

Топ-15 лайфхаков для работы с Python

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

Python — “самый мощный язык, который при этом можно читать”, — Пол Дюбуа.

Представляем 15 полезных приемов, которые пригодятся в решении повседневных проблем.

1. Наиболее частый элемент в списке

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

Большинство прибегает к использованию циклов для решения этой проблемы. Но вы можете упростить себе задачу, применив несколько встроенных функций.

2. Подсчет количества элементов

Этот лайфхак полезен для подсчета всех появляющихся элементов с помощью встроенной библиотеки Python. Вместо использования циклических и условных операторов и прочей логики, просто следуйте приведенному ниже примеру кода.

3. Повторение элемента в списке

Чтобы увеличить количество строк, можно использовать звездочку * . Но этот лайфхак применим и к спискам.

4. Списковое включение (быстрый способ)

Списковое включение — самый эффективный способ итерации любого списка. Это итерирование однострочного списка с включением в него цикла. Посмотрите приведенный ниже пример кода, чтобы понять, как это работает.

5. Преобразование изменяемых данных в неизменяемые

Изменяемые данные (например, словари или списки) — это структуры, к которым могут быть добавлены новые значения.

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

6. Функция в одну строку

Этот метод с использованием лямбды позволит создавать лаконичные функции в одну строку. Взгляните на пример кода ниже.

7. Применение функции ко всем элементам в списке

Этот прием полезен в тех случаях, когда нужно применить функцию ко всем элементам списка, а не к каждому отдельно.

8. Возврат нескольких значений из функции

Знаете ли вы, что можно осуществлять возврат нескольких значений из функции? Вот как это сделать. Ознакомьтесь с приведенным ниже примером кода.

9. Расчет времени выполнения

Этот простейший “трюк” поможет рассчитать время, необходимое для выполнения программы. Используя time-модуль, вы можете точно узнать, сколько времени требуется программе для выполнения кода.

10. Распечатывание ежемесячного календаря

А этот лайфхак — всего лишь скрытая функция Python, которая позволяет распечатывать ежемесячный календарь в формате таблицы.

11. Обратный список и строка

Скорее всего, вы используете обратную функцию для инверсионной записи списков или строк. Но знаете ли вы, как осуществить инверсию более эффективным способом?

12. Транспонирование 2d-массива

Этот лайфхак покажет, как выполнить транспонирование 2d-массива с помощью метода zip . Посмотрите пример кода ниже.

13. Get Method для словаря

Большинство разработчиков используют скобки, чтобы получить значение из словаря. Но сейчас рекомендуется использовать Get method .

При использовании метода скобок выдается ошибка, если ключ отсутствует. С помощью Get method вы получите “None” .

14. Превращение списка в одну строку

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

Но есть более быстрый и эффективный способ выполнения той же задачи с помощью одной строки кода.

15. Обработка ошибок во время выполнения

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

Заключение

Надеемся, что эти приемы и методы вам пригодятся. Рекомендуем продолжать практиковаться и каждый день узнавать что-то новое. Изучение лайфхаков не является чем-то обязательным. Но создавать свои собственные лайфхаки — это круто.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *