Оператор моржа := в Python

17 июля 2026
Автор

Антон Ларичев

Что такое оператор моржа

Оператор := (walrus operator, оператор моржа) был добавлен в Python 3.8 согласно PEP 572. Своё название он получил благодаря внешнему сходству с глазами и клыками моржа.

Его официальное название — оператор именованного выражения (named expression). Он позволяет присваивать значение переменной и одновременно использовать это значение как часть выражения.

До Python 3.8 присваивание и использование значения были разделены на два шага. Оператор := объединяет их в один.

Синтаксис

variable := expression

Важно понимать разницу:

# Обычное присваивание — это инструкция, не выражение
x = 10

# Оператор моржа — это выражение, которое возвращает значение
# и одновременно присваивает его переменной
(x := 10)

Ключевое свойство: := возвращает значение, поэтому его можно использовать внутри условий, циклов и генераторов.

Применение в циклах while

Самый распространённый и наглядный случай использования — цикл while, который читает данные до тех пор, пока они не закончатся.

Без оператора моржа:

line = file.readline()
while line:
    process(line)
    line = file.readline()

Здесь file.readline() вызывается дважды: один раз до цикла для инициализации, и ещё раз в конце каждой итерации. Это дублирование кода легко приводит к ошибкам, если нужно изменить логику чтения.

С оператором моржа:

while line := file.readline():
    process(line)

Теперь readline() вызывается только в одном месте. Условие цикла само читает строку, присваивает её переменной line и проверяет, не пустая ли она.

Ещё один классический пример — чтение пользовательского ввода:

# Без оператора моржа
command = input('Введите команду: ')
while command != 'quit':
    execute(command)
    command = input('Введите команду: ')

# С оператором моржа
while (command := input('Введите команду: ')) != 'quit':
    execute(command)

Скобки вокруг command := input(...) обязательны, потому что без них Python воспримет := неверно из-за приоритета операторов.

Применение в условных выражениях

Оператор моржа удобен, когда нужно вычислить значение, проверить его и использовать в одном блоке:

import re

text = 'Цена: 1500 рублей'

# Без оператора моржа
match = re.search(r'\d+', text)
if match:
    print(f'Найдено число: {match.group()}')

# С оператором моржа
if match := re.search(r'\d+', text):
    print(f'Найдено число: {match.group()}')

Во втором варианте переменная match доступна внутри блока if без предварительного объявления за его пределами.

Пример с проверкой длины строки:

def validate_username(username: str) -> str | None:
    if (n := len(username)) < 3:
        return f'Слишком короткое имя: {n} символов, минимум 3'
    if n > 20:
        return f'Слишком длинное имя: {n} символов, максимум 20'
    return None

error = validate_username('ab')
if error:
    print(error)  # Слишком короткое имя: 2 символа, минимум 3

Без := пришлось бы вычислять len(username) дважды или заводить отдельную переменную перед условием.

Применение в генераторах списков

Генераторы списков с := позволяют избежать повторного вычисления дорогостоящей функции:

import math

numbers = [1, 4, 9, 16, -1, 25, -4]

# Без оператора моржа — sqrt вычисляется дважды
results = [
    math.sqrt(n)
    for n in numbers
    if n >= 0 and math.sqrt(n) > 2
]

# С оператором моржа — sqrt вычисляется один раз
results = [
    root
    for n in numbers
    if n >= 0 and (root := math.sqrt(n)) > 2
]

print(results)  # [3.0, 4.0, 5.0]

Оператор := вычисляет math.sqrt(n) один раз, присваивает результат переменной root и сразу использует её в условии. Затем эта же переменная используется как результирующее значение элемента.

Другой пример — фильтрация и преобразование данных одновременно:

def parse_int(s: str) -> int | None:
    try:
        return int(s)
    except ValueError:
        return None

raw = ['1', 'abc', '3', '', '5', 'xyz']

# Получаем только валидные числа без двойного вызова parse_int
valid_numbers = [
    parsed
    for s in raw
    if (parsed := parse_int(s)) is not None
]

print(valid_numbers)  # [1, 3, 5]

Область видимости переменной

Переменная, объявленная через :=, попадает в область видимости объемлющего блока, а не ограничивается генератором или условием:

data = [1, 5, 2, 8, 3]

filtered = [y for x in data if (y := x * 2) > 6]
print(filtered)  # [10, 16, 6]
print(y)         # 6 — последнее присвоенное значение доступно снаружи

Это отличает := от обычных переменных внутри генераторов, которые недоступны снаружи. Будьте осторожны: если вы не ожидаете «утечки» переменной из генератора, это может привести к неожиданным результатам.

Реальный пример: парсинг конфигурации

Рассмотрим практический случай — обработка строк конфигурационного файла:

def parse_config(lines: list[str]) -> dict[str, str]:
    config = {}
    for line in lines:
        # Пропускаем комментарии и пустые строки
        line = line.strip()
        if not line or line.startswith('#'):
            continue
        # Присваиваем результат поиска и сразу проверяем
        if match := re.match(r'^(\w+)\s*=\s*(.+)$', line):
            key, value = match.group(1), match.group(2)
            config[key] = value
    return config

lines = [
    '# Настройки приложения',
    'host = localhost',
    'port = 8080',
    '',
    'debug = true',
]

print(parse_config(lines))
# {'host': 'localhost', 'port': '8080', 'debug': 'true'}

Реальный пример: поиск в связанном списке

class Node:
    def __init__(self, value: int, next: 'Node | None' = None):
        self.value = value
        self.next = next

def find_first_greater(node: Node | None, threshold: int) -> int | None:
    while node := node and node if node.value > threshold else node.next:
        if node.value > threshold:
            return node.value
        node = node.next
    return None

Впрочем, для связанных списков классический цикл while node: зачастую читабельнее. Оператор моржа — инструмент, а не цель сама по себе.

Когда не стоит использовать оператор моржа

Оператор := может сделать код короче, но не всегда — понятнее. Избегайте его в следующих случаях.

Когда переменная нужна только один раз:

# Излишнее усложнение
if (result := compute()) is not None:
    print('Готово')

# Лучше так
if compute() is not None:
    print('Готово')

Когда выражение становится слишком длинным:

# Трудно читать
if (data := fetch_data()) and (processed := transform(data)) and len(processed) > 10:
    save(processed)

# Лучше разбить на шаги
data = fetch_data()
if data:
    processed = transform(data)
    if len(processed) > 10:
        save(processed)

Вложенные := в одном выражении — почти всегда плохая идея:

# Избегайте такого
if (a := (b := func())) > 0:
    ...

Сравнение подходов: итого

Ситуация Без := С :=
Цикл с чтением данных Дублирование вызова Один вызов в условии
Проверка результата функции Переменная до if Переменная в условии
Генераторы с дорогой функцией Двойной вызов Один вызов через :=
Простое условие без переиспользования Чисто Излишне

Требования к версии Python

Оператор := доступен начиная с Python 3.8. Если ваш проект должен поддерживать Python 3.7 и ниже — использовать его нельзя.

Проверить версию:

python --version
# Python 3.11.4

Если вы получаете SyntaxError: invalid syntax при использовании :=, значит интерпретатор старше 3.8.

Итог

Оператор моржа := — полезный инструмент Python 3.8+, который позволяет:

  • Устранить дублирование вызовов функций в условиях и циклах
  • Сократить код без потери читаемости в правильном контексте
  • Писать лаконичные генераторы с промежуточными вычислениями

Главное правило: применяйте := тогда, когда он делает код яснее, а не просто короче. Если выражение с := требует пауз при чтении — лучше разбить его на отдельные строки.

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

Аннотации типов (Type Hints) в PythonСтрелочка вправо

Постройте личный план изучения Python до уровня Middle — бесплатно!

Python — часть карты развития Backend

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Все гайды по Python

Как отправлять запросы с помощью requests в PythonПочему Python выводит значение без команды printКак работает команда print в PythonВозможности Python для автоматизации задачРабота с JSON в Python на примерахPython get — методы получения данныхКак находить и исправлять ошибки в PythonРабота с данными через API и внешние сервисыСтруктура и оформление кода PythonОсновы Django с PythonПолезные приёмы в Python для повседневной работыИспользование locals в Python для отладкиИнтеграция PHP и PythonКак выполнять HTTPS-запросы в PythonFastAPI Python — быстрый старт: создание REST API с нуляКак работать с API в Python
Ввод целого числа в PythonВедение логов в PythonУдаление данных в Python с помощью removeОбработка исключений с помощью try/except в PythonФункция super() в Python — как вызвать метод родителяСоздание собственных контекстных менеджеров в PythonРабота с символами программирования PythonРабота с переменной X в PythonРабота с классами в PythonКак скачать Python на компьютерПростая программа на Python для начинающихОсновы Python для тех, кто начинаетЧто нового в Python 3Поддерживается ли Python 2 и стоит ли его использоватьPython 1 — с чего начиналась история языкаКоманда python print - полное руководство по выводу данныхПравила именования переменных в PythonПользовательские исключения в PythonОсновы Python coreОписание объектов PythonНаследование классов в Python — основы и примерыМножественное наследование в Python — примеры и MROКонтекстный менеджер with в Python — как работает и зачем нуженКомментарии в Python — однострочные, многострочные и docstringКакой Python выбрать для установкиКак вывести целое число с помощью print в PythonКак установить Python на Windows macOS и LinuxКак пользоваться консолью PythonКак получить последний элемент в PythonКак найти значение в PythonКак настроить PythonКак использовать print для строк в PythonКак работает интерпретатор PythonИнструкция по работе с PythonБлок finally в обработке исключений PythonЦелые числа в PythonАбстрактные классы в Python — ABC и abstractmethod
Pydantic: валидация данных в Python
Загрузка данных PythonУправление проектами на GitHub с PythonСоздание бота на PythonСоздание веб-приложений на Flask PythonСоздание интерфейсов Python QTСоздание игр с PygameСоздание GUI в PythonКак работать со словарями в PythonРабота с библиотеками через Python PackagingРабота со временем в Python при помощи модуля timePython name — особенности переменнойМатематические операции в Python с модулем mathPython listing — что это и как использоватьPytest — тестирование на Python: полное руководствоОбработка изображений с OpenCV PythonNumPy в Python — основы и применение в задачахМашинное обучение с PythonИспользование Anaconda с PythonМодуль contextlib в Python — утилиты для контекстных менеджеровБиблиотеки Python и их применение в проектах
Возврат значений из функции в PythonВложенные функции в PythonСоздание собственных декораторов в PythonРабота с функцией map в PythonЦикл while в Python и примеры использованияОбработка чисел, введённых через input в PythonОсновные операторы в Python с примерамиУсловные выражения if else в Python для начинающихКак выполняется вызов функций call в PythonПродвинутые генераторы в Python — send, throw, close и корутиныПозиционные и именованные аргументы в PythonОбъявление переменных и управление областью видимости в PythonПередача аргументов по ссылке и по значению в PythonПередача аргументов через args и kwargs в PythonОсновные методы Python и примеры их использованияОператор match/case в Python 3.10+ — основы структурного сопоставленияПаттерны match/case в Python — деструктуризация, guard и вложенные шаблоныПрактические примеры match/case в Python — реальные сценарии примененияЛокальные и глобальные переменные в PythonЧасто используемые команды PythonКлючевые слова global и nonlocal в PythonКак создавать функции в PythonКак работает сборщик мусора в PythonКак работает область видимости переменных в PythonКак работает функция callable в PythonКак работает функция any и all в PythonКак проверить тип переменной в PythonКак передать функцию как аргумент в PythonКак использовать функцию isinstance в PythonКак использовать функцию filter в PythonКак использовать функцию filter в PythonКак использовать функцию eval безопасно в PythonКак использовать декораторы в PythonИзменяемые и неизменяемые типы данных в PythonГенераторы и yield в Python — как создавать и использоватьГенераторные выражения в Python — синтаксис и примерыФункции в Python и способы их вызоваФункции как объекты в PythonЧто такое замыкания в PythonЧто делает функция reduce в PythonЧто делает функция id в PythonАргументы по умолчанию в PythonАнонимные функции и lambda в PythonАлгоритмы на Python — примеры и объяснение
Запись данных в PythonУстановка pip в PythonУправление зависимостями requirement в PythonУправление библиотеками с помощью Python PackagingУдаление пробелов с помощью strip в PythonСтруктурирование кода в PythonСоздание исполняемого файла Python в exeРазбор traceback в модуле PythonРазбор site-packages в PythonРазбор Program Files в PythonРабота с Unicode кодировками в PythonРабота с системными функциями Python sysРабота с папкой AppData в PythonРабота с модулем logging в PythonРабота с каталогами в PythonРабота с CSV в PythonВиртуальная среда venv в Python — создание и настройкаКак создать простое приложение на PythonИспользование pip в Python для установки пакетовМодули в Python и организация кода в проектеИмпорт модулей в Python и правила подключенияРабота с файлами в Python пошаговоЧто делает компилятор Python и как он работаетПолучение строки из модуля PythonПодключение файлов в Python с includeПеременные среды в PythonСборка проекта с помощью packaging в PythonНастройка Python сервераИспользование Python на UbuntuИспользование консоли PythonИспользование кодировок в PythonИнициализация пакетов PythonИмпорт модулей PythonИмпорт имен в PythonСреда IDLE Python и базовые возможностиЧтение и запись TXT в PythonЧтение файлов в Python с помощью open file
Удаление элементов из списка PythonТипы данных в Python — обзор и рекомендацииОсновные операции со строками в PythonМетоды str в Python и обработка текстаСписки в Python и их ключевые методыСоздание списков данных в PythonРабота со строками и символами в PythonРабота со столбцами в PythonРабота со списком значений в PythonРабота с таблицами в Python с помощью DataFrameРабота с RFR в PythonРабота с пробелами в PythonРабота с массивами в PythonРабота с кортежами tuple PythonРабота с координатами X и Y в PythonРабота с ключами в PythonРабота с элементами данных PythonРабота с двоичными числами PythonРабота с данными в PythonРабота с данными NumPy PythonРабота с большими числами в PythonРабота с битами в PythonРабота с байтами в PythonЧто такое значение в Python и как его определитьМножества в Python и операции с нимиИспользование range в Python для цикловПроверка на четность в PythonПроверка числа в PythonПреобразование типов в PythonПреобразование списка в строку PythonПреобразование числа в строку в PythonПостроение графиков в PythonОпределение индекса элемента в PythonОкругление чисел в PythonОбъединение списков в Python с помощью zipМножества в PythonМассивы в Python и отличие от списковМассив чисел в PythonКортежи данных в PythonКак вычислить сумму чисел в PythonКак получить остаток от деления в PythonКак найти следующее число в PythonИспользование Unicode в PythonТип int в Python и его особенностиИндекс списка в PythonФункции для работы со строками в PythonЭлементы Python и способы доступа к нимДоступ к элементам массива в PythonДеление чисел в PythonРабота с данными в Python на практикеКак работать с числами в Python
Открыть базу знаний

Лучшие курсы по теме

Иконка молнииНовый
изображение курса

Основы Python

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Nest.js с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.6
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Docker и Ansible

Антон Ларичев
AI-тренажерыAI-тренажеры
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий