
Периодически меня увлекает решение задач по программированию путем сокращения Python-кода до одной строки. Хочу поделиться несколькими лайфхаками, которые помогли мне лучше справляться с этим в последние годы.
Примечание: не переусердствуйте с ними в производственном коде, иначе ваш PR — (Pull Request — запрос на слияние кода из разных веток в системе Git) может быть отклонен.
1) Тернарный оператор
Вот простой блок if-else, который выполняет присваивание с помощью =.

Тернарный оператор позволяет сократить блок if-else до одной строки кода.

Этот метод также подходит для блоков if-else с несколькими операторами elif.

Использование тернарного оператора чрезвычайно полезно, когда нужно сжать блок if-else в одну строку кода.
2) Распаковка кортежей
Распаковка кортежей позволяет выполнять несколько операций присваивания (=) в одной строке кода.

Обратите внимание, что можно заменить нужные значения на список/кортеж.

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

Хотя, если не требуется вводить так много переменных в левой части, можно добавить переменную *, чтобы перехватить все остальные неприсвоенные значения:

3) Генераторы списков/словарей/множеств
Генератор списков (list comprehension) позволяет изящно создавать список с помощью всего одной строки кода.

- Генератор словарей (dictionary comprehension) похож на генератор списков, но для генерации словарей используются фигурные скобки вместо квадратных, а также вводится пара ключ-значение, разделенная двоеточием.
- Генератор множеств (set comprehension) похож на генератор списков, но для генерации множеств используются только фигурные скобки вместо квадратных.

Все эти генераторы позволяют легко сократить циклы for до одной строки кода.
4) Цепочка методов
Цепочкой методов называется связывание нескольких вызовов методов в одной строке кода.
Допустим, у вас есть длинный email, как показано ниже. Вам надо извлечь имя (first name) и фамилию (last name), соединив их с помощью тире. Для этого можно использовать следующие шаги:

Однако эта запись занимает много строк кода. На самом деле ее можно сжать в одну строку с помощью цепочки методов.

Как видите, использование цепочки методов позволило сжать шаги a, b, c и d в одну строку.
Учтите: чтобы цепочка методов работала, необходимо убедиться, что каждый метод возвращает корректный вывод корректного типа.
5) Однострочные функции и блоки if/else
Тело функции не обязательно должно находиться под строкой def — можно также поместить тело функции справа от строки def.

То же самое касается блоков if/else — тело блока не обязательно должно находиться под строкой if/else.

Примечание 1-е: не делайте этого в производственном коде, если не хотите, чтобы ваш линтер обнаружил потенциальную ошибку, а ваш PR был отклонен (данный лайфхак предназначен исключительно для того, чтобы сжать код в одну строку).
Примечание 2-е: в одной строке может быть только одно двоеточие (после def или if/else).

6) Точка с запятой в Python
В некоторых случаях можно использовать точку с запятой, чтобы сжать несколько инструкций в одну строку.

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

7) Моржовый оператор (walrus)
Моржовый оператор ( := ) выполняет 2 действия:
- присваивает переменной значение, как это делает оператор присваивания ( = );
- возвращает само значение.
Проиллюстрируем это на простом примере:

В выражении ( x := 5 ) происходят два события:
- переменной x присваивается значение 5;
- выражение ( x := 5 ) само по себе возвращает значение 5 — вот почему можно использовать его в условии.
Оператор walrus экономит одну строку кода. А значит, многократное использование оператора walrus может сэкономить много строк кода.

Разберем строку (f:=fruits[n]) + f[::-1][1:]:
- сначала f присваивается fruits[n], после чего f — «apple»;
- можно снова использовать f после знака +, так как теперь f — «apple».
8) Лямбда-функции
Ключевое слово lambda позволяет определить функцию в одной строке кода.
Синтаксис лямбды — lambda input_params : return_value.
Вот 2 примера: 1) функции, определенные обычным образом и 2) лямбда-функции.

- lambda x:x+10 означает, что эта функция принимает один параметр x и возвращает x + 10;
- lambda a,b:a+b означает, что эта функция принимает два параметра (a, b) и возвращает a+b.
9) Рекурсия
Да, рекурсию можно использовать, чтобы сжать код в одну строку.
В качестве примера рассмотрим генерацию чисел Фибоначчи. Напомню: они имеют вид 0 1 1 2 3 5 8 13 … — каждое новое число равно сумме двух предыдущих.
Вот обычный способ написания функции, которая возвращает n-ое число Фибоначчи:

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

Согласитесь, с этим гораздо проще справиться.
Поскольку в этом фрагменте кода используются в основном блоки if-else, можно сжать его в одну строку с помощью тернарного оператора.

10) Использование eval()
Встроенная функция eval() принимает строку и оценивает ее как код Python.

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

А вот еще один изящный способ добиться этого с использованием eval():

- Сначала используем map(), чтобы преобразовать все целые числа в строку.
- Далее с помощью метода .join() создаем строку «1*2*3*4*5».
- Затем применяем метод eval для оценки строки, чтобы получить ответ.
Читайте также:
- 28 суперполезных фрагментов Python-кода для решения повседневных задач
- Отступы в Python: так ли это плохо?
- Почему большинство программистов выбирают Python
Читайте нас в Telegram, VK и Дзен
Перевод статьи Liu Zuo Lin 10: Things I Regret Not Knowing Earlier About Writing Python Code In One Line