Что такое оператор присваивания в выражении (walrus operator) в Python

Ответ

Оператор присваивания в выражении := (неофициально — «моржовый оператор» из-за сходства с глазами и бивнями моржа) был добавлен в Python 3.8. Он позволяет одновременно присвоить значение переменной и вернуть это значение в рамках одного выражения.

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

Классический пример: цикл while

Чтение файла по строкам до тех пор, пока не встретится пустая строка.

Без оператора :=

lines = []
line = f.readline()
while line:
    lines.append(line)
    line = f.readline()

С оператором := Код становится короче и выразительнее, так как присваивание и проверка происходят в одном месте.

lines = []
while (line := f.readline()):
    lines.append(line)

Другие полезные случаи применения:

  1. Условия if:

    # Вместо
    match = re.search(pattern, text)
    if match:
        print(match.group(0))
    
    # Можно написать
    if (match := re.search(pattern, text)):
        print(match.group(0))
  2. Генераторы списков (List Comprehensions):

    # Обработать только "дорогие" товары, сохранив результат вычисления
    cart = [{"name": "apple", "price": 1.2}, {"name": "banana", "price": 0.5}]
    expensive_items = [discounted_price for item in cart 
                       if (discounted_price := item['price'] * 0.9) > 1.0]
    # expensive_items будет [1.08]

Важное замечание: Следует использовать оператор := с осторожностью. В сложных выражениях он может ухудшить читаемость кода, что противоречит одному из главных принципов Python (The Zen of Python — "Readability counts").

Ответ 18+ 🔞

А, ну это же про того самого моржа, который с бивнями! Python 3.8 подкинул нам эту штуку, оператор :=. Выглядит как :=, а народ сразу прозвал «моржовый», потому что, если прищуриться, похоже на мордашку моржа — эти двоеточие-глазки и бивень-равно. Охуенно же!

Зачем он вообще, этот морж? А чтобы не повторяться, как попугай нахуй. Бывает, вычисляешь что-то, потом это же значение и проверяешь, и ещё куда-то пихаешь. Так вот этот оператор позволяет в одном выражении и присвоить переменной значение, и сразу его вернуть. Экономия на спичках, но иногда — просто песня.

Классика жанра: цикл while

Вот смотри, старый добрый способ читать файл, пока строки не кончатся.

Без моржа (по-старинке):

lines = []
line = f.readline()
while line:
    lines.append(line)
    line = f.readline()

Видишь, как мы дважды вызываем f.readline()? Один раз перед циклом, второй — в самом конце тела. Неэлегантно, блядь, как-то.

А теперь с моржом (по-новой, с огоньком):

lines = []
while (line := f.readline()):
    lines.append(line)

Во! Красота! Всё в одном месте: и чтение строки, и проверка, что она не пустая, и присвоение её в line. Чисто, аккуратно, в рот меня чих-пых!

А ещё где его впендюрить можно?

  1. В условиях if (чтобы не дёргать функцию дважды):

    # Раньше: вызов, присвоение, потом проверка.
    match = re.search(pattern, text)
    if match:
        print(match.group(0))
    
    # Теперь: всё в одну строчку, красиво и не паримся.
    if (match := re.search(pattern, text)):
        print(match.group(0))

    Сэкономили одну строчку и один потенциально тяжёлый вызов. Нехуёво.

  2. В генераторах списков (тут вообще магия начинается):

    cart = [{"name": "apple", "price": 1.2}, {"name": "banana", "price": 0.5}]
    expensive_items = [discounted_price for item in cart 
                       if (discounted_price := item['price'] * 0.9) > 1.0]
    # expensive_items будет [1.08]

    Смотри, какой трюк! Мы в условии if вычисляем скидочную цену, присваиваем её в переменную discounted_price и тут же проверяем, больше ли она единицы. А если условие прошло — эта самая вычисленная цена уже готова и летит прямо в результирующий список! Без моржа пришлось бы либо считать дважды, либо городить огород. А так — элегантно, ёпта.

Но, чувак, главное — не обосраться с ним!

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