Распаковка кортежей в 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 позволяет распаковывать кортежи и любые другие итерируемые объекты в любом месте кода, где вам может потребоваться дать описательные имена к элементам внутри данных объектов.
Возможно будет интересно
🏆 Hello, world!
Мы вчера запустили новый www.pylot.me. Должны были в следующую среду, но запустили вчера.
Как практиковаться в Python?
Для улучшения качества знаний и повышения уровня программиста, необходим постоянный практикум. Где можно это организовать самостоятельно, и как практиковаться в Python?
Условные конструкции и сопоставление структурных шаблонов
Шпаргалка по условным конструкциям и сопоставлению структурных шаблонов