upd:
96.1K
10

Кортежи в Python (tuple)

Содержание:развернуть
Кортеж (tuple) — ещё один вид последовательностей в Python.

По своей природе они очень схожи со списками, но, в отличие от последних, являются неизменяемыми.

# кортеж immutable_tuple = (4, 5, 6) immutable_tuple[0] = 404 > Traceback (most recent call last): immutable_tuple[0] = 404 TypeError: 'tuple' object does not support item assignment# список mutable_list = [7, 8, 9] mutable_list[0] = 1 print(mutable_list) > [1, 8, 9]

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

👉 Некоторые особенности кортежей:

  • они упорядочены по позициям;
  • tuple могут хранить и содержать внутри себя объекты любых типов (и даже составных);
  • доступ к элементам происходит по смещению, а не по ключу;
  • в рамках этой структуры данных определены все операции, основанные на применении смещения (индексирование, срез);
  • кортежи поддерживают неограниченное количество уровней вложенности;
  • кортежи хранят указатели на другие объекты, а значит их можно представлять, как массивы ссылок;
  • они позволяют очень просто менять местами значения двух переменных.
x = 100 y = 200 x, y = y, x print(x) > 200 print(y) > 100

Примеры кортежей

# пустой кортеж empty_tuple = () # кортеж из 4-х элементов разных типов four_el_tuple = (36.6, 'Normal', None, False) # пример tuple, что содержит вложенные элементы nested_elem_tuple = (('one', 'two'), ['three', 'four'], {'five': 'six'}, (('seven', 'eight'), ('nine', 'ten'))) print(nested_elem_tuple) > (('one', 'two'), ['three', 'four'], {'five': 'six'}, (('seven', 'eight'), ('nine', 'ten')))

Зачем использовать кортеж вместо списка

Тем, кто уже успел познакомиться со списками в Python, может показаться не очевидным смысл использования кортежей. Ведь фактически, списки могут делать всё то же самое и даже больше. Это вполне естественный вопрос, но, разумеется, у создателей языка найдётся на него ответ:

  • Неизменяемость — именно это свойство кортежей, порой, может выгодно отличать их от списков.
  • Скорость — кортежи быстрее работают. По причине неизменяемости кортежи хранятся в памяти особым образом, поэтому операции с их элементами выполняются заведомо быстрее, чем с компонентами списка.
  • Безопасность — неизменяемость также позволяет им быть идеальными кандидатами на роль констант. Константы, заданные кортежами, позволяют сделать код более читаемым и безопасным.
  • Использование tuple в других структурах данных — кортежи применимы в отдельных структурах данных, от которых python требует неизменяемых значений. Например ключи словарей (dicts) должны состоять исключительно из данных immutable-типа.

💡 Кроме того, кортежи удобно использовать, когда необходимо вернуть из функции несколько значений:

def get_status(service_name): return None, f"service {service_name} is OK!" print(type(get_status('nginx'))) > <class 'tuple'> error, message = get_status('nginx') print(error) print(message) > None > service nginx is OK!

Работа с кортежами

Создание

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

Способ №1: Литеральное объявление:

literal_creation = ('any', 'object') print(literal_creation) > ('any', 'object') print(type(literal_creation)) > <class 'tuple'>

Способ №2: Через функцию tuple():

tuple_creation = tuple('any iterable object') print(tuple_creation) > ('a', 'n', 'y', ' ', 'i', 't', 'e', 'r', 'a', 'b', 'l', 'e', ' ', 'o', 'b', 'j', 'e', 'c', 't') print(type(tuple_creation)) > <class 'tuple'>

💁‍♀️ Важно, чтобы аргумент, передаваемый в tuple() был итерируемым объектом:

incorrect_creation = tuple(777) > Traceback (most recent call last): incorrect_creation = tuple(777) TypeError: 'int' object is not iterable

Упаковка

Упаковкой кортежа называют присваивание его какой-то переменной, что, по сути, совпадает с операцией объявления.

Стоит обратить внимание 2 момента:

  1. Выражения some_tuple = (11, 12, 13) и some_tuple = 11, 12, 13 тождественны.
  2. Для объявления кортежа, включающего один единственный элемент, нужно использовать завершающую запятую:
is_tuple = ('a',) is_tuple_too = 'b', not_a_tuple = 'c' print(type(is_tuple)) print(type(is_tuple_too)) print(type(not_a_tuple)) > <class 'tuple'> > <class 'tuple'> > <class 'str'>

Распаковка

Обратная операция, смысл которой в том, чтобы присвоить значения элементов кортежа отдельным переменным.

notes = ('Do', 'Re', 'Mi', 'Fa', 'Sol', 'La', 'Si') do, re, mi, fa, sol, la, si = notes print(mi) > Mi

Количество переменных должно совпадать с числом элементов tuple

Однако, если необходимо получить лишь какие-то отдельные значения, то в качестве "ненужных" переменных позволено использовать символ нижнего подчеркивания "_":

night_sky = 'Moon', 'Stars' moon, _ = night_sky print(moon) > Moon

Обращение к элементу и поиск в кортеже

Обратиться к элементу кортежа можно по номеру его позиции. Причём как с начала, так и с конца:

# Mike - [0], Leo - [1], Don - [2], Raph - [3] turtles = ('Mike', 'Leo', 'Don', 'Raph') # Mike - [-4], Leo - [-3], Don - [-2], Raph - [-1] print(turtles[1]) print(turtles[-2]) print(turtles[2] == turtles[-2]) > Leo > Don > True

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

input_box = ('firstbox', (15, 150)) # помним про индексацию, ведущую своё начало с 0 print(input_box[1][1]) > 150

Узнать, присутствует ли объект среди элементов кортежа, можно с помощью оператора in:

song = ('Roses', 'are', 'Red') print('Red' in song) print('Violet' in song) > True > False

Сравнение

tuple_A = 2 * 2, tuple_B = 2 * 2 * 2, tuple_C = 'a', tuple_D = 'z', tuple_E = (42, 'maximum') tuple_F = (42, 'minimum') tuple_Z = 999, # при сравнении кортежей, числа сравниваются по значению print(tuple_A < tuple_B) > True # строки в лексикографическом порядке print(tuple_C < tuple_D) > True # при равенстве элементов на одинаковых позициях, сравниваются элементы на следующих print(tuple_E < tuple_F) > True # сравнение элементов продолжается до первого неравенства print(tuple_Z < tuple_F) > False

Перебор

Наиболее простым и очевидным способом перебрать элементы кортежа является обход его в цикле for:

my_tuple = ('Wise', 'men', 'say', 'only', 'fools', 'rush', 'in') # Вывести все элементы кортежа for word in my_tuple: print(word) > Wise men say only fools rush in

Сортировка

Нет ничего проще, чем отсортировать готовый кортеж. В этом наш друг и помощник — прекрасная функция sorted():

not_sorted_tuple = (10**5, 10**2, 10**1, 10**4, 10**0, 10**3) print(not_sorted_tuple) > (100000, 100, 10, 10000, 1, 1000) sorted_tuple = tuple(sorted(not_sorted_tuple)) print(sorted_tuple) > (1, 10, 100, 1000, 10000, 100000)

Удаление

Добавить или удалить элемент содержащийся в tuple нельзя, по причине всё той же неизменяемости. Однако сам кортеж стереть с цифрового лица Земли возможно. Оператор del к нашим услугам:

some_useless_stuff = ('sad', 'bad things', 'trans fats') del some_useless_stuff print(some_useless_stuff) > Traceback (most recent call last): print(some_useless_stuff) NameError: name 'some_useless_stuff' is not defined

Методы и особые операции

Срез

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

tuple[start:fin:step]

Где start — начальный элемент среза (включительно), fin — конечный (не включительно) и step— "шаг" среза.

float_tuple = (1.1, 0.5, 45.5, 33.33, 9.12, 3.14, 2.73) print(float_tuple[0:3]) > (1.1, 0.5, 45.5) # тождественная запись print(float_tuple[:3]) > (1.1, 0.5, 45.5) # если не указывать конечное значение, будут выведены все элементы до конца print(float_tuple[0:]) > (1.1, 0.5, 45.5, 33.33, 9.12, 3.14, 2.73) # не указывать начальное - с начала print(float_tuple[:]) > (1.1, 0.5, 45.5, 33.33, 9.12, 3.14, 2.73) # выведем элементы с шагом 2 print(float_tuple[-7::2]) > (1.1, 45.5, 9.12, 2.73) # отрицательный шаг позволит вывести tuple в обратном порядке print(float_tuple[::-1]) > (2.73, 3.14, 9.12, 33.33, 45.5, 0.5, 1.1)

Длина кортежа

Используя функцию len(), получаем длину/количество элементов:

php = ('p', 'h', 'p') print(len(php)) > 3

Конкатенация

Для tuple определена операция конкатенации:

storm_1 = ('Lightning',) union = (' and ',) storm_2 = ('Thunder',) print(storm_1 + union + storm_2) > ('Lightning', ' and ', 'Thunder')

Повторение

Как и в случае с конкатенацией, для кортежей, впрочем, как и для строк, определена операция повторения:

dog_do = ('woof!',) print(dog_do * 3) > ('woof!', 'woof!', 'woof!')

Индекс заданного элемента

Метод index() позволяет получить индекс элемента. Достаточно передать нужное значение элемента, как аргумент метода:

rom = ('I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X') print(rom.index('X')) > 9

Число вхождений элемента

Метод count() ведёт подсчет числа вхождений элемента в кортеж.

AT = ('Finn', 'Jake', 'BiMo', 'Marceline', 'Princess Bubblegum', 'BiMo') print(AT.count('Finn')) > 1 print(AT.count('BiMo')) > 2

Преобразование

tuple → str

Представляем вашему вниманию лёгкий способ преобразовать кортеж в строку при помощи метода join():

game_name = ('Breath', ' ', 'of', ' ', 'the', ' ', 'Wild') game_name = ''.join(game_name) print(game_name) > Breath of the Wild

tuple → list

Тут всё ещё проще. Для такой конвертации необходимо всего лишь передать кортеж, как аргумент функции list():

dig_tuple = (1111, 2222, 3333) print(dig_tuple) > (1111, 2222, 3333) dig_list = list(dig_tuple) print(dig_list) > [1111, 2222, 3333]

tuple → dict

А вот для преобразования кортежа в словарь придётся применить небольшую хитрость, а именно — генератор словарей:

score = (('Eric', 65000), ('Stephany', 87000)) score_dict = dict((x, y) for x, y in score) print(score_dict) > {'Eric': 65000, 'Stephany': 87000}

Именованные кортежи

Мощная особенность и настоящая гордость языка.

Именованный кортеж (или named tuple) позволяет программисту обращаться к элементу кортежа не по индексу, а через удобочитаемый заранее заданный идентификатор.

Покажем на примере:

# для начала импортируем сам модуль from collections import namedtuple citizen = namedtuple("Citizen", "name age status") Alex = citizen(name='Alex Mercer', age=27, status='show businessman') print(Alex.name) > Alex Mercer print(Alex.status) > show businessman

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

Tuple index out of range

Такая ошибка может возникнуть, например, при запуске следующего кода:

i_initiate_error = ('west', 'north', 'east', 'south') print(i_initiate_error[4])

Причина её возникновения в том, что нельзя получить доступ к индексу кортежа за пределами его длины. Эта ошибка может возникать и при совсем нетривиальных обстоятельствах, однако суть её останется прежней. Начинающим программистам стоит помнить, что индексация кортежей начинается с 0, а не с 1.


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

2
😭
6
😕
21
😃
129
😍
Комментарии (10)
Сначала популярные
Сначала новые
По очереди
WTF
11 мес. 25 дней назад

Можете пояснить как это работает? Все переменные получаются типа str, конечно же конкатенация работает, если добавить запятые в скобки, то получается tuple, а не строка....

Конкатенация

Для tuple определена операция конкатенации:

storm_1 = ('Lightning') Union = (' and ') storm_2 = ('Thunder') print(storm_1 + Union + storm_2) > Lightning and Thunder

Или может быть вы хотели показать такой результат?

storm_1 = ('Lightning',) Union = (' and ',) storm_2 = ('Thunder',) print(storm_1 + Union + storm_2) > ('Lightning', ' and ', 'Thunder')
2
ответить
Pythonchik
18 дней назад

Спасибо за комментарий, код примера исправил 👌

1
ответить
еще 1 ответ
Аделина
1 год 2 месяца назад

Спасибо за объяснение! Достойно!

2
ответить
поклоннимк
1 год назад

спасибо большое очень полезно не знала бы что делать без вас

2
ответить
Евгений
9 мес. 8 дней назад

Не согласен с последней фразой. Наоборот если не нужна изменяемость данных то следует использовать именно кортежи. Как минимум это защитит от случайного изменения данных, как максимум кортежи ещё и меньше памяти занимают.

1
ответить
Pythonchik
18 дней назад

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

4
ответить
Евген
18 дней назад

Можно ли задать кортеж:

list_of_colors = (RED = (255, 0, 0), GREEN = (0, 255, 0))

И если да, как правильно это сделать?

0
ответить
Pythonchik
18 дней назад

Можно сделать кортеж словарей:

list_of_colors = ({"RED": (255, 0, 0)}, {"GREEN": (0, 255, 0)}) print(list_of_colors) > ({'RED': (255, 0, 0)}, {'GREEN': (0, 255, 0)})

Или использовать именованный кортеж:

from collections import namedtuple color = namedtuple("Color", "name code") list_of_colors = ( color(name='RED', code=(255, 0, 0)), color(name='GREEN', code=(0, 255, 0)) ) print(list_of_colors) > (Color(name='RED', code=(255, 0, 0)), Color(name='GREEN', code=(0, 255, 0)))

Как сделать правильно, зависит от конкретной задачи.

0
ответить
MipoX
10 мес. 8 дней назад

Топ! Коротко и по сути!

0
ответить
Содержание:развернуть
вверх
Может понравиться
Основы
upd:
Словари в Python (dict)