Кортежи (tuple)

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

Списки заключаются в квадратные скобки, а кортежи – в круглые.

Словарь представляет собой хэш-таблицу пар ключ-значение. Список и кортеж — это упорядоченная коллекция предметов. Словарь — неупорядоченная коллекция.

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

Кортеж является неизменным объектом. Операции добавления или удаления невозможны для объекта кортежа.

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

По аналогии со списками кортежи в Python — это стандартный тип, позволяющий хранить значения в виде последовательности. Они полезны в тех случаях, когда необходимо передать данные, не позволяя изменять их. Эти данные могут быть использованы, но в оригинальной структуре изменения не отобразятся.

Как вы могли заметить, кортежи очень похожи на списки. По сути, они являются неизменяемыми списками. Это значит, что после создания кортежа хранимые в нем значения нельзя удалять или менять. Добавлять новые также нельзя:

В этом руководстве вы познакомитесь с кортежами Python в подробностях:

  • Узнаете, как их создавать. Увидите, что значит неизменяемый тип на примерах
  • Разберетесь, чем кортежи в Python отличаются от списков
  • Познакомитесь с операциями: срезами, конкатенацией, умножением и так далее
  • Увидите встроенные функции
  • Научитесь присваивать сразу несколько значений кортежами

Кортеж Python

Эта структура данных используется для хранения последовательности упорядоченных и неизменяемых элементов.

Кортежи создают с помощью круглых скобок (). Для создания нужно написать следующее:

cake = ('c','a','k','e') 
print(type(cake))

Примечание: type() — это встроенная функция для проверки типа данных переданного параметра.

Кортежи могут включать однородные и разнородные значения. Но после объявления их уже нельзя будет поменять:

mixed_type = ('C',0,0,'K','I','E')

for i in mixed_type:
    print(i,":",type(i))
C : 
0 : 
0 : 
K : 
I : 
E : 
# Попробуйте изменить 0 на «O»
mixed_type[1] = "O"
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

 in ()
----> 1 mixed_type[1] = 'O'  # Попробуйте изменить 0 на «O»


TypeError: 'tuple' object does not support item assignment

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

Кортежи можно создавать и вот так:

numbers_tuple = 1,2,3,4,5
print(type(numbers_tuple))

Кортежи против списков

Как вы могли заметить, кортежи очень похожи на списки. По сути, они являются неизменяемыми списками. Это значит, что после создания кортежа хранимые в нем значения нельзя удалять или менять. Добавлять новые также нельзя:

numbers_tuple = (1,2,3,4,5)
numbers_list = [1,2,3,4,5]

# Добавим число в кортеж
numbers_tuple.append(6)
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

 in ()
      3 
      4 # Добавим число в кортеж
----> 5 numbers_tuple.append(6)


AttributeError: 'tuple' object has no attribute 'append'

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

# Добавим число в список
numbers_list.append(6)
numbers_list.append(7)
numbers_list.append(8)

# Удалить число из списка
numbers_list.remove(7)
print(numbers_list)
[1, 2, 3, 4, 5, 6, 8]

Но зачем использовать этот тип данных, если он неизменяемый?

Кортежи не только предоставляют доступ только для чтения к элементам, но и работают быстрее списков. Рассмотрим в качестве примера следующий код:

>>> import timeit
>>> timeit.timeit('x=(1,2,3,4,5,6,7,8,9)', number=100000)
0.0018976779974764213
>>> timeit.timeit('x=[1,2,3,4,5,6,7,8,9]', number=100000)
0.019868606992531568

Какую роль играет неизменяемость в случае с кортежами?

Согласно официальной документации Python неизменяемый — это «объект с фиксированным значением», но в отношении кортежей «значение» — это чересчур размытый термин. Лучше использовать idid определяет расположения объекта в памяти.

Рассмотрим подробнее:

# Кортеж 'n_tuple' со списком в качестве одного из его элементов.
n_tuple = (1, 1, [3,4])

# Элементы с одинаковым значением имеют одинаковый идентификатор.
id(n_tuple[0]) == id(n_tuple[1])
True
# Элементы с разным значением имеют разные идентификаторы.
id(n_tuple[0]) == id(n_tuple[2])
False
print(id(n_tuple[0]), id(n_tuple[2]))
4297148528, 4359711048
n_tuple.append(5)
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

 in ()
----> 1 n_tuple.append(5)


AttributeError: 'tuple' object has no attribute 'append'

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

n_tuple[2].append(5)
n_tuple
(1, 1, [3, 4, 5])

Это позволяет изменять оригинальный кортеж? Куда в таком случае делась их неизменяемость?

Суть в том, что id списка в кортеже не меняется несмотря на добавленный в него элемент 5.

id(n_tuple[2])
4359711048

Теперь вы знаете следующее:

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

  • Вы не можете добавлять в них новые элементы. У этого типа нет методов append() или extend()
  • Удалять элементы тоже нельзя, также из-за неизменяемости. Методов remove() и pop() здесь нет
  • Искать элементы в кортеже можно, потому что этот процесс его не меняет
  • Разрешено использовать оператор in для проверки наличия элемента в кортеже

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

Если вы хотите узнать больше о списках Python, обязательно ознакомьтесь с этим руководством!

Стандартные операции с кортежами

Python предоставляет несколько способов для управления кортежами. Рассмотрим их на примерах.

Срезы

Значение индекса первого элемента в кортеже — 0. По аналогии со списками эти значения можно использовать с квадратными скобками [] для получения доступа к кортежам:

numbers = (0,1,2,3,4,5)
numbers[0]
0

Можно использовать и отрицательные значения:

numbers[-1]
5

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

[Начальный индекст (включен):Конечный индекс (исключен):Частота]

Частота в данном случае является опциональным параметром, а его значение по умолчанию равно 1.

# Элемент с индексом 4 исключен
numbers[1:4]
(1, 2, 3)
# Это возвращает все элементы в кортеже
numbers[:]
(0, 1, 2, 3, 4, 5)
# Частота = 2
numbers[::2]
(0, 2, 4)

Совет: значение частоты может быть и негативным, чтобы развернуть кортеж.

numbers[::-1]
(5, 4, 3, 2, 1, 0)

Объединение кортежей

Можно объединять кортежи для создания нового объекта. Операция объединения выполняет конкатенацию двух кортежей.

x = (1,2,3,4)
y = (5,6,7,8)

# Объединение двух кортежей для формирования нового кортежа
z = x + y 
print(z)
(1, 2, 3, 4, 5, 6, 7, 8)
y = [5,6,7,8]
z = x + y
print(z)
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

 in ()
      1 y = [5,6,7,8]
----> 2 z = x + y
      3 print(z)


TypeError: can only concatenate tuple (not "list") to tuple

Разрешается объединять только определенные типы данных. Так, попытка соединить кортеж и список закончится ошибкой.

Умножение кортежей

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

x = (1,2,3,4)
z = x*2
print(z)
(1, 2, 3, 4, 1, 2, 3, 4)

Функции кортежей

В отличие от списков у кортежей нет методов, таких как append()remove()extend()insert() или pop() опять-таки из-за их неизменяемости. Но есть другие:

count() и len()

count() возвращает количество повторений элемента в кортеже.

a = [1,2,3,4,5,5]
a.count(5)
2

len() — длину кортежа:

a = (1,2,3,4,5)
print(len(a))
5

any()

Функцию any() можно использовать, чтобы определить являются ли элементы кортежа итерируемыми. Если да, то она вернет True.

a = (1,)
print(any(a))
True

Обратите внимание на запятую (,) в объявлении кортежа a. Если ее не указать при создании объекта с одним элементом? Python предположит, что вы по ошибке добавили лишнюю пару скобок (это ни на что не влияет), но тип данных в таком случае — это не кортеж. Поэтому важно не забывать использовать запятую при объявлении кортежа с одним элементом.

И снова к функции any. В булевом контексте значение элемента не имеет значения. Пустой кортеж вернет False, а кортеж с хотя бы одним элементом — True.

b = ()
print(any(b))
False

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

tuple()

Функция tuple() используется для конвертации данных в кортеж. Например, так можно превратить список в кортеж.

a_list = [1,2,3,4,5]
b_tuple = tuple(a_list)
print(type(b_tuple))

min() и max()

Функция max()q возвращает самый большой элемент последовательности, а min() — самый маленький. Возьмем следующий пример:

print(max(a))
print(min(a))
5
A

Эти функции можно использовать и для кортежей со строками.

# Строка «Apple» автоматически преобразуется в последовательность символов.
a = ('Apple') 
print(max(a))
p

sum()

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

sum(a)
28

sorted()

Чтобы получить кортеж с отсортированными элементами, используйте sorted() как в следующем примере:

a = (6,7,4,2,1,5,3)
sorted(a)
[1, 2, 3, 4, 5, 6, 7]

Но важно отметить, что возвращаемый тип — список, а не кортеж. При этом последовательность в оригинальном объекте неизменна, а сам он остается кортежем.

Присваивание несколько кортежей

Кортежи можно использовать для присваивания нескольких значений одновременно. Вот так:

a = (1,2,3)
(one,two,three) = a
print(one)
1

a — это кортеж из трех элементов и (one, two, three) — кортеж трех переменных. Присваивание (one, two, three) кортежу a присваивает каждое значение a каждой переменной: onetwo и three по очереди. Это удобно, если нужно присвоить определенному количеству переменных значений в кортеже.

Выводы

Теперь вы знаете, что такое кортежи, как их создавать, какие самые распространенные операции, и как ими можно управлять. Также — распространенные методы структур Python. А в качестве бонуса научились присваивать нескольким переменным разные значения.

Кортежи и операции с ними

Кортеж – это упорядоченная неизменяемая коллекция произвольных данных.

Для задания кортежа достаточно перечислить значения через запятую:

a = 1,2

или же, это эквивалентно такой записи:

a=(1,2,3)

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

b = 1,     или    b = (1,)

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

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

x,y = (1,2)

Но вот так:

x,y = (1,2,3)

уже возникнет ошибка, т.к. число значений в кортеже меньше числа переменных.

Для определения длины кортежа (числа его элементов), используется уже знакомая вам функция

len(a)

Далее, доступ к элементам кортежа осуществляется также как и к элементам списков:

– по индексу:

a[0]
a[2]
a[-1]

– через срезы:

a[1:2]
a[0:-1]
a[:3]
a[1:]
a[:]

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

b = a[:]

не создает копию кортежа – это будут ссылки на один и тот же кортеж:

print(id(a), id(b))

увидим одно и то же значение id.

Если кортежи так похожи на списки, то в чем их преимущество перед ними? Другими словами: в каких случаях следует использовать кортеж вместо списка? Во-первых, кортеж – это неизменяемый тип, то есть, мы в отличие от списков, не можем выполнять такие операции:

a[1] = 100

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

d = {}
d[a] = "кортеж"

В-третьих, кортеж занимает меньше памяти, чем такой же список, например:

lst=[1,2,3]
t = (1,2,3)
print(lst.__sizeof__())
print(t.__sizeof__())

Как видите, размер кортежа меньше, чем списка. Здесь использован метод __sizeof__, который возвращает размер данных в байтах.

И, наконец, в-четвертых, операции с кортежами выполняются быстрее, чем со списками, например, перебор элементов или доступ к отдельному элементу.

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

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

a = ()
b = tuple()
print(type(a), type(b))

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

a = ()
a = a +  (1,)

или для добавления в начало кортежа:

a = (2,3) + a

Также можно добавить вложенный кортеж:

a += (("a", "hello"),)

или делать дубли в кортеже:

b = (0,)*10
b = ("hello", "world")*5

Все эти операции вполне допустимы.

Далее, функция tuple позволяет создавать кортежи на основе любых упорядоченных списков:

a = tuple([1,2,3])
a = tuple("Привет мир")

И обратно, из кортежа можно сформировать список:

t = (1,2,3)
lst = list(t)

Также кортежи могут хранить самые разные данные:

a = (True, [1,2,3], "hello", 5, {"house": "дом"})

Причем, смотрите, если обратиться, например, к списку:

a[1]

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

a[1].append("5")

То есть, неизменяемость кортежа относится к его структуре элементов и переменным

которые ссылаются на конкретные объекты. Но, если объекты могут изменяться, то это никто не запрещает делать.

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

del a[1]

но можно удалить его целиком:

del a

после этого кортеж a перестанет существовать.

Методы кортежа

У кортежа имеется два таких метода:

a = ("abc", 2, [1,2], True, 2, 5)
a.count("abc")
a.count(2)

который возвращает число найденных элементов с указанным значением. Если элемент не найден:

a.count("a")

то возвращается число 0.

Следующий метод:

a.index(2)

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

a.index(2,3)

позволяет задавать индекс начала поиска элемента. В данном случае поиск будет начинаться с третьего индекса. А последний третий аргумент:

a.index(2, 3, 5)

определяет индекс, до которого идет поиск (не включая его). Если же записать вот так:

a.index(2, 3, 4)

то возникнет ошибка, т.к. в поиск будет включен только 3-й индекс и там нет значения 2.

Задания для самопроверки

1. Дан кортеж:

p = (“+792345678”, “+792345478”, “+792355678”, “+592345678”, “+392345678”, “+7923456558”)

Нужно вывести все номера, начинающиеся с «+7».

2. Имеется набор оценок в виде строки:

“Оценки: 5, 4, 3, 4, 2, 4, 5, 4”

Необходимо создать кортеж, в котором находились бы только оценки в виде целых чисел:

(5, 4, 3, 4, 2, 4, 5, 4)

3. Вывести значения кортежа:

((1,2,3),(3,4,5),(6,7,8))

в виде таблицы:

1 – 2 – 3
4 – 5 – 6
7 – 8 – 9

Полезная ссылка

Повтор

Что такое кортеж

Кортеж (tuple) представляет последовательность элементов, которая во многом похожа на список за тем исключением, что кортеж является неизменяемым (immutable) типом. Поэтому мы не можем добавлять или удалять элементы в кортеже, изменять его.

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


tom = (“Tom”, 23)
print(tom) # (“Tom”, 23)


Также для определения кортежа мы можем просто перечислить значения через запятую без применения скобок:


tom = “Tom”, 23
print(tom) # (“Tom”, 23)


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


tom = (“Tom”,)


Для создания кортежа из другого набора элементов, например, из списка, можно передать список в функцию tuple(), которая возвратит кортеж:


data = [“Tom”, 37, “Google”]
tom = tuple(data)
print(tom) # (“Tom”, 37, “Google”)


С помощью встроенной функции len() можно получить длину кортежа:


tom = (“Tom”, 37, “Google”)
print(len(tom)) # 3


Обращение к элементам кортежа
Обращение к элементам в кортеже происходит также, как и в списке, по индексу. Индексация начинается также с нуля при получении элементов с начала списка и с -1 при получении элементов с конца списка:


tom = (“Tom”, 37, “Google”, “software developer”)
print(tom[0]) # Tom
print(tom[1]) # 37
print(tom[-1]) # software developer


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


tom[1] = “Tim”


При необходимости мы можем разложить кортеж на отдельные переменные:


name, age, company, position = (“Tom”, 37, “Google”, “software developer”)
print(name) # Tom
print(age) # 37
print(position) # software developer
print(company) # Google


Получение подкортежей
Как и в списках, можно получить часть кортежа в виде другого кортежа

tom = (“Tom”, 37, “Google”, “software developer”)

#получем подкортеж с 1 по 3 элемента (не включая)

print(tom[1:3]) # (37, “Google”)

#получем подкортеж с 0 по 3 элемента (не включая)

print(tom[:3]) # (“Tom”, 37, “Google”)

#получем подкортеж с 1 по последний элемент

print(tom[1:]) # (37, “Google”, “software developer”)

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

Когда функция возвращает несколько значений, фактически она возвращает в кортеж:


def get_user():
name = “Tom”
age = 22
company = “Google”
return name, age, company

user = get_user()
print(user) # (“Tom”, 37, “Google”)


При передаче кортежа в функцию с помощью оператора * его можно разложить на отдельные значения, которые передаются параметрам функции:


def print_person(name, age, company):
print(f”Name: {name} Age: {age} Company: {company}”)

tom = (“Tom”, 22)
print_person(*tom, “Microsoft”) # Name: Tom Age: 22 Company: Microsoft

bob = (“Bob”, 41, “Apple”)
print_person(*bob) # Name: Bob Age: 41 Company: Apple


Перебор кортежей
Для перебора кортежа можно использовать стандартные циклы for и while. С помощью цикла for:


tom = (“Tom”, 22, “Google”)
for item in tom:
print(item)


С помощью цикла while:


tom = (“Tom”, 22, “Google”)

i = 0
while i < len(tom):
print(tom[i])
i += 1


Проверка наличия значения
Как для списка с помощью выражения элемент in кортеж можно проверить наличие элемента в кортеже:


user = (“Tom”, 22, “Google”)
name = “Tom”
if name in user:
print(“Пользователя зовут Tom”)
else:
print(“Пользователь имеет другое имя”)

https://www.youtube.com/watch?v=eWa_nwiE2PY