Упаковка данных в Python — кортеж tuple

Представьте себя функцией. Да, это не просто, и все же...

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

Как упаковать

Для функции get_contacts(email) доступны несколько способов упаковки данных в более сложную структуру: словарь dict(), кортеж tuple() и еще несколько других. Рассмотрим подробнее последний вариант — tuple.

Предположим, вы вызвали функцию get_contacts('dmitry@example.com'), она нашла такого человека и хочет вернуть его контакты:

full_name = 'Никифоров Дмитрий Анатольевич'
city = 'Москва'
phone_number = '929-876-54-32'

Функция создает кортеж — tuple() —, чтобы поместить в него все контакты:

contacts = (full_name, city, phone_number)

Круглые скобки и запятые указывают Python, что из перечисленных переменных full_name, city и phone_number нужно создать новую структуру данных:

print(type(contacts))  # выведет <class 'tuple'>
print(contacts)

Последний вызов print() выведет на экран такое:

('Никифоров Дмитрий Анатольевич', 'Москва', '929-876-54-32')

Теперь функция get_contacts сможет вернуть любое количество данных. Все они будут упакованы в один кортеж — tuple.

Что делать, если получили tuple

Разберем как работать с tuple на примере стандартной функции divmod. Она возвращает результат деления с остатком:

divmod(100, 3)  # выведет (33, 1)
divmod(2, 3) # выведет (0, 2)

Функция divmod возвращает кортеж из двух чисел — результата целочисленного деления и остаток от деления.

Мы можем сохранить результат в переменную:

div_tuple = divmod(100, 3)
print(div_tuple)  # выведет (33, 1)

Добраться до каждого из двух чисел можно по индексу:

div_tuple = divmod(100, 3)
print(div_tuple[0])  # выведет 33
print(div_tuple[1])  # выведет 1

Индексы в коде [0] и [1] сильно осложняют чтение, поэтому полезно давать говорящие названия:

div_tuple = divmod(100, 3)
int_division = div_tuple[0]
remainder = div_tuple[1]

print(int_division)  # выведет 33
print(remainder)  # выведет 1

Такой паттерн рекомендуется к использованию и встречается настолько часто, что в Python ввели упрощенную короткую запись:

(int_division, remainder) = divmod(100, 3)
print(int_division)  # выведет 33
print(remainder)  # выведет 1

Запись похожа на создание кортежа - те же скобки и запятые, но работает это в обратную сторону. Называется "распаковкой".

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

int_division, remainder = divmod(100, 3)
print(int_division)  # выведет 33
print(remainder)  # выведет 1

Последняя форма записи распаковки наиболее распространена и рекомендуется к использованию.

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

contacts = full_name, city, phone_number

В коде внутри функций часто встречается еще более короткая запись:

return full_name, city, phone_number

Вызов return сообщает интерпретатору Python, что функция завершает свою работу и хочет вернуть результат. А все перечисленное справо от return будет упаковано в кортеж — tuple.

Ссылки по теме: