Обзор операторов Python: как работают арифметика, логика и присваивание

Раздел: Основы Python -> Операторы языка

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

Операторы Python: основы и нюансы

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

Арифметические операторы

Python поддерживает стандартные арифметические операции: +, -, *, /, // (целочисленное деление), % (остаток от деления), ** (возведение в степень).


a = 10
b = 3
print(a + b)   # 13
print(a - b)   # 7
print(a * b)   # 30
print(a / b)   # 3.3333333333333335
print(a // b)  # 3
print(a % b)   # 1
print(a ** b)  # 1000

операции языка python (операции в языке python)

Важно: оператор / всегда возвращает float, даже если результат целый. Оператор // выполняет floor division (округление вниз).

Операторы сравнения

==, !=, <, >, <=, >= сравнивают значения и возвращают bool.


print(5 == 5)  # True
print(5 != 5)  # False
print(5 < 3)   # False

Ошибки: сравнение чисел с плавающей точкой может привести к неожиданным результатам из-за погрешностей. Рекомендуется использовать math.isclose.

Логические операторы

and, or, not используются для объединения условий.


x = True
y = False
print(x and y)  # False
print(x or y)   # True
print(not x)    # False

Ленивое вычисление: and и or вычисляют второй операнд только при необходимости.

Операторы присваивания

=, +=, -=, *=, /= и т.д. изменяют значение переменной.


n = 10
n += 5  # n = 15
n //= 2 # n = 7

Битовые операторы

&, |, ^, ~, <<, >> работают с целыми числами на уровне битов.


print(5 & 3)  # 1 (0101 & 0011 = 0001)
print(5 | 3)  # 7 (0101 | 0011 = 0111)
print(5 ^ 3)  # 6 (0101 ^ 0011 = 0110)
print(~5)     # -6 (инверсия двух дополнения)
print(5 << 1) # 10 (сдвиг влево = умножение на 2)
print(5 >> 1) # 2 (сдвиг вправо = целочисленное деление на 2)

Операторы членства и идентичности

in, not in проверяют принадлежность элемента последовательности. is, is not проверяют идентичность объектов (один и тот же объект в памяти).


print(2 in [1,2,3])  # True
print(2 is 2)        # True (малые целые кэшируются)
a = [1,2]
b = [1,2]
print(a is b)        # False (разные объекты)
print(a == b)        # True (равные значения)

Типичная ошибка: путать is с ==. is сравнивает идентичность, а не равенство.

Как одновременно получить целую часть и остаток от деления?

Вместо двух операций // и % можно использовать встроенную функцию divmod:


result = divmod(10, 3)
print(result)  # (3, 1)

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

Проблема: При отрицательных числах поведение divmod отличается из-за floor division. Например, divmod(-10, 3) вернет (-4, 2). Для математически корректного остатка нужно использовать модуль math.fmod.

Как присвоить значение и сразу использовать его в выражении?

Начиная с Python 3.8, доступен оператор присваивания := (walrus). Он позволяет присвоить значение переменной внутри выражения, устраняя дублирование кода.


if (n := len(some_list)) > 10:
    print(f"Длинный список: {n} элементов")

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

Как заменить if-else на компактную форму?

Тернарный оператор (условие? значение_если_True : значение_если_False) в Python записывается как x if условие else y.


age = 20
status = "совершеннолетний" if age >= 18 else "несовершеннолетний"
print(status)

Проблема: Тернарный оператор снижает читаемость, если условие длинное. Лучше использовать обычный if-else для сложных случаев.

Как правильно расставить приоритеты при смешивании операторов?

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


print(2 + 3 * 4)   # 14 (умножение раньше)
print((2 + 3) * 4) # 20

Проблема: Путаница между битовыми и логическими операторами: битовые имеют более высокий приоритет, чем логические. Например, True & False or True вычисляется как (True & False) or True = False or True = True. Если задумано иначе, нужны скобки.

Как проверить, что переменная не None, и одновременно присвоить значение по умолчанию?

Оператор or можно использовать для присваивания значения по умолчанию, если переменная ложна.


name = input("Введите имя: ") or "Гость"
print(name)

Проблема: Этот трюк не различает None и пустую строку, так как обе ложны. Для специфичной проверки на None используйте x is None.

Расширенные примеры использования операторов

1. Операторы в списковых включениях

Комбинация арифметических и логических операторов в list comprehension позволяет компактно генерировать последовательности.

Пример

result = [x ** 2 for x in range(10) if x % 2 == 0 and x != 0]
print(result)  # [4, 16, 36, 64]
[4, 16, 36, 64]

2. Битовые маски и сдвиги

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

Пример

# Установка, снятие и проверка бита
flags = 0b1010  # 10
# Установить бит 1 (разряд 1 = 2)
flags |= 1 << 1  # flags = 0b1010 | 0b0010 = 0b1010 (уже установлен)
# Проверить бит 3
print((flags >> 3) & 1)  # 1 (так как 0b1010, бит 3 = 1)
# Сбросить бит 1
flags &= ~(1 << 1)
print(bin(flags))  # 0b1000
1
0b1000

3. Перегрузка операторов в пользовательских классах

Специальные методы, такие как __add__, __eq__, позволяют определить поведение операторов для собственных объектов.

Пример

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __add__(self, other):
        if isinstance(other, Vector):
            return Vector(self.x + other.x, self.y + other.y)
        return NotImplemented
    def __repr__(self):
        return f"Vector({self.x}, {self.y})"

v1 = Vector(1, 2)
v2 = Vector(3, 4)
v3 = v1 + v2
print(v3)  # Vector(4, 6)
Vector(4, 6)

4. Тернарный оператор в лямбда-функциях

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

Пример

max_func = lambda a, b: a if a > b else b
print(max_func(5, 10))  # 10

# Более сложный пример: сортировка строк по длине с учетом регистра
strings = ["Python", "java", "C++", "JavaScript"]
sorted_strings = sorted(strings, key=lambda s: len(s) if s.islower() else -len(s))
print(sorted_strings)
10
['java', 'C++', 'JavaScript', 'Python']

5. Оператор @ для матричного умножения

В Python 3.5+ введен оператор @ для вызова метода __matmul__. Используется в библиотеках вроде NumPy для матричного умножения.

Пример

# Пример с вложенными списками (без NumPy)
class Matrix:
    def __init__(self, data):
        self.data = data
    def __matmul__(self, other):
        # Упрощенная реализация умножения матриц 2x2
        result = [[0]*2 for _ in range(2)]
        for i in range(2):
            for j in range(2):
                for k in range(2):
                    result[i][j] += self.data[i][k] * other.data[k][j]
        return Matrix(result)
    def __repr__(self):
        return '\n'.join(str(row) for row in self.data)

A = Matrix([[1,2],[3,4]])
B = Matrix([[5,6],[7,8]])
C = A @ B
print(C)
[19, 22]
[43, 50]

6. Приоритеты и скобки: сложные выражения

Показательный пример, где приоритет важен для правильного результата.

Пример

x = 10
y = 20
z = 30
# Без скобок: and имеет приоритет над or, но or и and одинаковый приоритет? На самом and > or.
print(x < y and y < z or x == z)  # True (так как (x < y and y < z) = True, or True = True)
print(x < y and (y < z or x == z))  # True (то же самое, но скобки меняют порядок? нет, y
True
True
True

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

7. is vs == с неизменяемыми и изменяемыми объектами

Разница между сравнением идентичности и равенства особенно заметна на примере строк и списков.

Пример

# Строки: малые строки могут интернироваться
s1 = "hello"
s2 = "hello"
print(s1 is s2)  # True (возможно, интернирование)
s3 = "hello!"
s4 = "hello!"
print(s3 is s4)  # False (не всегда)
print(s3 == s4)  # True

# Списки: всегда разные объекты
l1 = [1, 2, 3]
l2 = [1, 2, 3]
print(l1 is l2)  # False
print(l1 == l2)  # True
True
False
True
False
True

Операции в языке Python - comments

En
операции языка python (python)