Перейти к основному содержимому

Однострочные приёмы Python

Разработчику

См. также: обзор по всем языкам · Типы данных · Функции · Работа с типами

Общая идея однострочников в коде — в разделе «Код». Ниже — десять приёмов, которые часто встречаются в скриптах, ноутбуках и на собеседованиях: каждый укладывается в одну строку (иногда плюс import).


Обмен, строки, числа

Обмен двух переменных

a, b = b, a

Справа создаётся кортеж (b, a), слева значения распаковываются в имена. Временная переменная tmp не нужна. Подробнее про кортежи и return a, b — в Функции в Python.


Разворот строки

s[::-1]

Срез [start:stop:step] с step = -1 идёт от конца к началу. Строки в Python неизменяемы — получается новая строка, исходная s не меняется. Другие способы (reversed, цикл) длиннее; срез — идиома. См. строки в типах данных.


Разворот списка

my_list[::-1] # новый list, исходный не меняется
my_list.reverse() # на месте, возвращает None

Срез с шагом -1 — та же идиома, что и для строк. На месте — только метод reverse(). Ещё три варианта (reversed(), циклы) и таблица выбора — в коллекции — списки.


Проверка палиндрома

s == s[::-1]

Сравнение строки с её разворотом. Для учебных задач достаточно; в проде часто нормализуют регистр и убирают пробелы:

t = "".join(ch.lower() for ch in s if ch.isalnum())
is_palindrome = t == t[::-1]

Факториал через math.prod

import math

math.prod(range(1, n + 1)) # n >= 0; для n == 0 произведение пустого range — 1

range(1, n + 1) даёт множители 1, 2, …, n. Модуль math появился в стандартной библиотеке давно; prod — с Python 3.8. Для n < 0 факториал не определён — проверяйте вход отдельно. Альтернатива — functools.reduce или цикл, если зависимость от math нежелательна.


Списки и словари

Выравнивание вложенного списка (flatten)

[i for sub in lst for i in sub]

Вложенное списковое включение: внешний цикл по sub, внутренний — по элементам. Работает для списка списков одного уровня. Для произвольной глубины — itertools.chain.from_iterable или рекурсия. В Python 3.12+ у list есть метод sum(lst, []), но он медленный на больших данных — включение предпочтительнее.


Чётные числа из диапазона

[x for x in range(10) if x % 2 == 0]

Шаблон включения с условием: 0, 2, 4, 6, 8. Тот же смысл — filter(lambda x: x % 2 == 0, range(10)), но включение читается привычнее в Python. Подробнее про lambda, map и filterанонимные функции; см. также циклы и итерации.


Слияние двух словарей

{**d1, **d2}

Распаковка обоих словарей в литерал: ключи из d2 перекрывают совпадающие ключи из d1 (порядок вставки в Python 3.7+ предсказуем). Для изменения на местеd1.update(d2) или с Python 3.9 — d1 | d2. Подробнее про dictтипы данных.


Подсчёт частот элементов

from collections import Counter

Counter(lst)

Counter ведёт себя как словарь «элемент → количество». Для строки Counter("hello") считает буквы. См. модуль collections.


Уникальные элементы

set(lst)

set убирает дубликаты; порядок в старых версиях не гарантировался, в CPython 3.7+ порядок вставки сохраняется для set, но для стабильного порядка уникальных значений используйте dict.fromkeys(lst) или sorted(set(lst)).


Список строк в одну строку

" ".join(lst)

join вызывают у разделителя (строки), аргумент — итерируемый из строк. Элементы должны быть типа str; иначе — str(x) в генераторе: " ".join(str(x) for x in lst). Обратная операция — s.split().


Walrus в условии

if (n := len(data)) > 10:
print(f"{n} items")

Оператор := (Python 3.8+) присваивает значение переменной внутри выражения и возвращает его — удобно, когда результат нужен и в условии, и в теле блока. Тот же приём работает в while (line := input()) != "quit". Подробнее — оператор walrus и управляющие конструкции.


Сводная таблица

ЗадачаOne-linerНужен import
1Обмен a, ba, b = b, a
2Разворот строкиs[::-1]
3Палиндромs == s[::-1]
4Факториалmath.prod(range(1, n + 1))math
5Flatten[i for sub in lst for i in sub]
6Чётные 0…9[x for x in range(10) if x % 2 == 0]
7Слить dict{**d1, **d2} или d1 | d2 (3.9+)
8ЧастотыCounter(lst)collections
9Уникальныеset(lst)
10Склейка' '.join(lst)

Аналоги в других языках

Сравнительная таблица по JavaScript, Java, C# и Go — в Однострочные приёмы в коде. В JavaScript, например, обмен — [a, b] = [b, a], слияние объектов — {...d1, ...d2}, уникальные — [...new Set(arr)].


Когда не увлекаться

Production и командный код

Однострочник уместен в REPL, тесте или коротком скрипте. В модуле, который сопровождает команда, длинное включение или цепочка вызовов лучше разбить на именованные шаги — так проще отлаживать и покрывать тестами. См. рефакторинг и pytest.

ИИ-ассистенты часто предлагают «умные» однострочники; перед вставкой в проект проверьте граничные случаи (n = 0, пустой lst, None в списке для join) и PEP 8 — длина строки и читаемость.


Дальше: списковые включения и генераторы · встроенные функции any, all, zip · модуль itertools

См. также

Другие статьи этого же раздела в боковом меню (как на странице "О разделе").