W3docs

Присвоение нескольких значений

Как присваивать несколько значений в Python: распаковка кортежей, одно значение для нескольких переменных, звёздочное присваивание и частые ошибки.

Присвоение нескольких значений в Python

Python позволяет присваивать значения нескольким переменным в одном операторе. Ниже рассмотрены четыре распространённых шаблона, которые встречаются в реальном коде:

  1. Множественное присваивание — разные значения разным переменным в одной строке.
  2. Цепочечное присваивание — одно и то же значение сразу нескольким переменным.
  3. Распаковка итерируемых объектов — извлечение элементов из списка, кортежа или любого итерируемого объекта.
  4. Звёздочное присваивание — сбор оставшихся элементов переменной длины в список.

Каждый шаблон описан ниже с запускаемыми примерами и возможными ошибками.

Множественное присваивание (распаковка кортежа)

Наиболее распространённая форма использует список имён через запятую слева и соответствующий список значений справа:

variable1, variable2, variable3 = value1, value2, value3

Python упаковывает правую часть во временный кортеж, а затем распаковывает его в имена слева, слева направо. Количество имён и значений должно совпадать точно; в противном случае Python выбросит ValueError.

Присвоение трёх переменных разных типов в одной строке:

python— editable, runs on the server

Вывод:

Python
3.7
True

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

Обмен значениями переменных

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

x = 5
y = 10

# Before swapping
print("Before swapping")
print("x =", x)
print("y =", y)

# Swap in one line — no temp variable needed
x, y = y, x

# After swapping
print("After swapping")
print("x =", x)
print("y =", y)

Вывод:

Before swapping
x = 5
y = 10
After swapping
x = 10
y = 5

В большинстве других языков этот обмен требует третьей вспомогательной переменной. Семантика упаковки в кортеж в Python делает однострочный вариант безопасным.

ValueError: несовпадение количества

Если количество значений не совпадает с количеством имён, Python немедленно выбрасывает ValueError:

a, b = 1, 2, 3        # too many values
# ValueError: too many values to unpack (expected 2)

a, b, c = 1, 2        # too few values
# ValueError: not enough values to unpack (expected 3, got 2)

Если вы видите эту ошибку, подсчитайте имена слева и значения справа — они должны быть равны, либо нужно использовать звёздочное присваивание (см. ниже).

Цепочечное присваивание (одно значение, несколько переменных)

Чтобы задать нескольким переменным одинаковое начальное значение, используйте цепочку операторов присваивания:

x = y = z = 0
print(x, y, z)

Вывод:

0 0 0

Python вычисляет 0 один раз и связывает все три имени с одним объектом. Для неизменяемых объектов (целых чисел, строк, кортежей) это работает корректно. Будьте осторожны с изменяемыми значениями по умолчанию — все три имени указывают на один и тот же объект-список:

# Pitfall: shared mutable object
a = b = c = []
a.append(1)
print(b)   # [1]  — b is the same list, not a copy!

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

a, b, c = [], [], []

Распаковка итерируемого объекта

Можно распаковать любой итерируемый объект — список, кортеж, строку, диапазон и т. д. — напрямую в переменные:

a, b, c = [10, 20, 30]
print(a, b, c)

Вывод:

10 20 30

Это тот же механизм, что и множественное присваивание; Python не различает, является ли правая часть литеральным кортежем или переменной-списком. Например, распаковка кортежа работает идентично:

coords = (51.5, -0.1)
lat, lon = coords
print(lat)   # 51.5
print(lon)   # -0.1

Подробнее об этом шаблоне см. в главе Распаковка кортежей.

Звёздочное присваивание (расширенная распаковка)

Если вы не знаете, сколько элементов содержит итерируемый объект, добавьте перед одним из имён *, чтобы собрать оставшиеся элементы в список:

first, *rest = [10, 20, 30, 40]
print(first)   # 10
print(rest)    # [20, 30, 40]

Имя со звёздочкой может находиться в любом месте списка целевых переменных — в начале, середине или конце:

first, *middle, last = [10, 20, 30, 40]
print(first)    # 10
print(middle)   # [20, 30]
print(last)     # 40
*head, second_last, last = range(1, 6)
print(head)         # [1, 2, 3]
print(second_last)  # 4
print(last)         # 5

Правила звёздочного присваивания:

  • В одном операторе допускается только одно имя со звёздочкой.
  • Имя со звёздочкой всегда собирает list, даже если совпадает с нулём или одним элементом.
  • Все имена без звёздочки должны соответствовать ровно одному элементу.

Когда использовать каждый шаблон

ШаблонТипичный случай использования
a, b = 1, 2Возврат нескольких значений из функции; обмен двух переменных
x = y = z = 0Инициализация группы счётчиков или флагов одним значением
a, b, c = my_listРаспаковка последовательности фиксированной длины в осмысленные имена
first, *rest = itemsОтделение головы от хвоста в списке неизвестной длины

Связанные темы

Практика

Практика
Which of the following are valid ways to assign multiple values in Python?
Which of the following are valid ways to assign multiple values in Python?
Was this page helpful?