Распаковка кортежей в Python Python

Распаковка кортежей в Python

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

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

Альтернатива неинформативным и жестко закодированным индексам

Допустим, мы имеем кортеж first_tuple, состоящий из 3-х элементов:

>>> first_tuple = (2, 1, 3)

Тогда, для того чтобы получить доступ к каждому элементу данного кортежа, первое, что напрашивается на ум – обратиться к этим элементам через их индекс:

>>> print(first_tuple[0], first_tuple[1], first_tuple[2])
2 1 3

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

>>> x, y, z = first_tuple

Операция присваивания из вышеприведенного примера, как раз и называется распаковкой кортежа. Такое название прямо отражает сущность данной операции, в которой кортеж, состоящий из трех элементов просто, был распакован в три переменные (x, y, и z):

>>> print(x, y, z)
2 1 3

Зачастую, использование кортежей в Python коде обусловлено лишь необходимостью объединения каких-либо значений вместе. С этой точки зрения, распаковку кортежей можно воспринимать просто, как отмену предыдущего объединения вышеназванных значений. В принципе, с нашим кортежем first_tuple мы поступили абсолютно аналогичным образом, когда сначала объединили в нем три значения, а затем обратно распаковали эти значения в отдельные поименованные переменные.

Важно отметить, что если мы попытаемся распаковать наш кортеж из трех элементов не в три, а в меньшее или большее число переменных, то получим ошибку:

>>> x, y = first_tuple
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 2)

При распаковке какого-либо картежа всегда необходимо, чтобы его структура и перемененных, в которые он распаковывается, совпадали. Проще говоря, количество переменных, в которые распаковывается ваш картеж должно соответствовать количеству элементов самого этого картежа.

Распаковка кортежей для доступа к каждому их элементу, прежде всего, позволяет предотвратить использование жестко закодированных индексов, а также обеспечивает доступ к элементам кортежей по понятным информативно-описательным именам.

Распаковка кортежей без применения знака равенства

На практике распаковка кортежей чаще всего используется не в операторах присваивания с применением знака равенства, а в for циклах.

Но, прежде чем рассматривать распаковку кортежей в циклах, давайте подготовим себе исходные данные для этой цели. В частности, давайте вызовем метод items() для словаря furniture с тем, чтобы получить итерацию кортежей из двух элементов:

>>> furniture = {"tables": 2, "chairs": 3, "stands": 0}
>>> furniture.items()
dict_items([('tables', 2), ('chairs', 3), ('stands', 0)])

Каждый полученный нами таким образом двухэлементный кортеж на самом деле представляет собой пару ключ-значение для каждого элемента в нашем словаре. Давайте попробуем отобразить кортежи для каждого элемента этого словаря с помощью цикла for:

>>> for item in furniture.items():
...     print(item)
...
('tables', 2)
('chairs', 3)
('stands', 0)

Из предыдущего раздела данной статьи мы уже знаем, что можем распаковать каждый элемент кортежа в соответствующую поименованную переменную. Давайте попробуем это сделать и с кортежами для элементов нашего словаря. Каждый из таких картежей, содержащий пару ключ-значение для соответствующего элемента словаря мы распакуем в переменную furniture и переменную amount соответственно:

>>> for item in furniture.items():
...     furniture, amount = item
...     print(furniture, amount)
...
tables 2
chairs 3
stands 0

Фактически же распаковка наших кортежей в отдельной строке внутри тела цикла с использованием оператора присваивания (=) было излишеством. Ведь на самом деле при каждой итерации цикла for в самой строке с определением этого цикла происходит так называемое неявное присваивание, когда в переменную, находящуюся между for и in, присваивается результат выражения, находящегося справа от in.

Таким образом, вышеприведенный пример мы можем переписать в несколько более компактной форме, производя распаковку наших кортежей прямо в строке с определением for цикла:

>>> for furniture, amount in furniture.items():
...     print(furniture, amount)
...
tables 2
chairs 3
stands 0

Следовательно, в строке с определением for цикла нам вообще не была нужна промежуточная переменная item поскольку все, что можно поместить слева от знака равенства в операторе присваивания, с таким же успехом мы можем разместить между for и in в цикле for. Вообще же, первая (определяющая) строка цикла for явится в вашей практике тем наиболее распространенным местом, куда вам потребуется распаковывать, как разнообразные кортежи, так и другие итерируемые объекты.

Выводы

В данной статье были изложены особенности распаковки последовательностей данных на примере кортежей. Однако распаковка может применяться не только к кортежам, но и к любым итерируемым объектам в Python. Именно поэтому распаковку кортежей также называют множественным присваиванием или итерируемой распаковкой.

Чаще всего вы будете сталкиваться именно с распаковками итерируемых двухэлементных или же трехэлементных кортежей при их переборе в for циклах. Хотя, на самом деле Python позволяет распаковывать кортежи и любые другие итерируемые объекты в любом месте кода, где вам может потребоваться дать описательные имена к элементам внутри данных объектов.

Практический Python для начинающих
Практический Python для начинающих

Станьте junior Python программистом за 7 месяцев

 7 месяцев

Возможно будет интересно

🏆 Hello, world! Python
Новичок
🏆 Hello, world!

Мы вчера запустили новый www.pylot.me. Должны были в следующую среду, но запустили вчера.

2022-10-04
Как практиковаться в Python? Python
Новичок
Как практиковаться в Python?

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

2022-10-19
Условные конструкции и сопоставление структурных шаблонов Шпаргалки
Новичок
Условные конструкции и сопоставление структурных шаблонов

Шпаргалка по условным конструкциям и сопоставлению структурных шаблонов

2022-11-09