Чем отличается кортеж от списка в Python

Кортежи и списки – это два из четырех доступных в Python встроенных типов данных. Оба типа полезны и на первый взгляд могут показаться похожими. Но у них есть существенные различия. Каждый из этих типов данных имеет собственные use cases. О том, чем отличается кортеж от списка в Python, мы бы и хотели сегодня поговорить.

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

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

Итак, давайте начнем!

Что из себя представляют кортежи и списки?

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

Кортеж имеет класс «кортеж» (англ. tuple): <class 'tuple'>. А список имеет класс «список» (list): <class 'list'>.

Чтобы проверить, к какому классу относится объект, вы всегда можете использовать встроенную функцию type(). Просто передайте в нее нужный вам объект в качестве аргумента. Таким образом можно проверить, является ли этот объект кортежем или списком.

Допустим, вы создали кортеж с именем my_tuple. Проверить его тип можно так:

type(my_tuple)

# output
# <class 'tuple'>

Это особенно полезно для отладки.

Теперь давайте посмотрим, что у кортежей и списков общего.

Сходства между кортежами и списками в Python

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

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

Кортежи и списки могут быть пустыми или содержать один или даже несколько элементов в одной переменной.

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

Чтобы создать пустой кортеж, вы либо используете круглые скобки сами по себе, либо применяете метод-конструктор tuple().

type(())
# <class 'tuple'>

my_tuple = ()
type(my_tuple)
# <class 'tuple'>

# или...

my_tuple = tuple()
type(my_tuple)
# <class 'tuple'>

Для создания пустого списка вы также можете использовать пустые скобки (только квадратные), или вызвать метод-конструктор list().

type([])
# <class 'list'>

# my_list = []

# или...

my_list = list()

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

age = (28,)

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

age = tuple((28,))
type(age)
# <class 'tuple'>

Если вы не добавите запятую в конце, Python не распознает это как кортеж.

age = (28)
type(age)
# <class 'int'>

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

age = [28]
type(age)
# <class 'list'>

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

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

Однако вы также можете создать кортеж или список, содержащий смесь разных типов данных.

my_information = ["Dionysia",27,True,"Lemonaki",7,"Python",False]

# или...

my_information = list(("Dionysia",27,True,"Lemonaki",7,"Python",False))
print(my_information)
# ['Dionysia', 27, True, 'Lemonaki', 7, 'Python', False]

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

information = ("Jimmy",50,True,"Kate",50)
print(information)
# ('Jimmy', 50, True, 'Kate', 50)

# или...

my_information = ["Dionysia",27,True,"Lemonaki",7,"Python",False,27,"Python",27]

Если вы забудете запятые, вы получите следующее сообщение об ошибке:

information = ("Jimmy" 50,True,"Kate",50)
# File "<stdin>", line 1
#     information = ("Jimmy" 50,True,"Kate",50)
#     ^
# SyntaxError: invalid syntax

my_information = ["Dionysia" 28,True,"Lemonaki",7,"Python",False]
#  File "<stdin>", line 1
#     my_information = ["Dionysia" 28,True,"Lemonaki",7,"Python",False]
#                                  ^
# SyntaxError: invalid syntax

Чтобы проверить длину списка или кортежа и узнать, сколько элементов в нем находится, можно использовать метод len().

my_information = ["Dionysia",27,True,"Lemonaki",7,"Python",False,27,"Python",27]
len(my_information)
# 7
[python_ad_block]

В Python и кортежи, и списки поддерживают распаковку

По сути, при создании кортежа или списка значения «упаковываются» в одну переменную, как мы упоминали ранее.

front_end = ("html", "css", "javascript")

Эти значения можно «распаковать» и присвоить отдельным переменным.

front_end = ("html","css","javascript")
content,styling,interactivity = front_end

content
# 'html'

styling
# 'css'

interactivity
# 'javascript'

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

front_end = ("html","css","javascript")

content,styling = front_end
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# ValueError: too many values to unpack (expected 2)


# или...


front_end = ("html","css","javascript")

content,styling,interactivity,data =  front_end
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# ValueError: not enough values to unpack (expected 4, got 3)

Элементы и списков,и кортежей доступны по индексу

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

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

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

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

Напомним, что индексация в Python (как и в большинстве языков программирования) начинается с 0. То есть первый элемент имеет индекс 0, второй элемент имеет индекс 1 и так далее.

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

names = ("Jimmy","Timmy","John","Kate")
names[2]
# 'John'

Или так:

programming_languages = ["Python","JavaScript","Java","C"]
programming_languages[0]
# 'Python'

programming_languages[1]
# 'JavaScript'

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

Чем кортеж отличается от списка?

Кортежи, в отличие от списков, неизменяемы

В Python кортежи неизменяемы. Это означает, что после создания кортежа элементы внутри него не могут измениться.

Если вы попытаетесь изменить значение одного из элементов, вы получите сообщение об ошибке:

names = ("Jimmy","Timmy","John","Kate")

names[2] = "Kelly"
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# TypeError: 'tuple' object does not support item assignment

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

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

Когда использовать кортежи

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

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

Когда использовать списки

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

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

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

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

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

Давайте рассмотрим несколько простых способов изменения списков.

Как изменять списки в Python

Поскольку списки изменяемы, вам необходимо знать несколько основных способов обновления данных в них.

Как обновить элемент в списке в Python

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

#general syntax
list_name[index] = new_value
programming_languages = ["Python","JavaScript","Java","C"]
print(programming_languages)
# ['Python', 'JavaScript', 'Java', 'C']

programming_languages[2] = "C++"
print(programming_languages)
# ['Python', 'JavaScript', 'C++', 'C']

Как добавить элементы в список в Python

В Python есть несколько встроенных методов для добавления элементов в списки.

Метод .append() добавляет один новый элемент в конец списка.

#general syntax
list_name.append(item)

programming_languages = ["Python","JavaScript","Java","C"]
print(programming_languages)
# ['Python', 'JavaScript', 'Java', 'C']

programming_languages.append("C++")

print(programming_languages)
# ['Python', 'JavaScript', 'Java', 'C', 'C++']

Чтобы добавить один элемент на определенную позицию, используется метод .insert().

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

#general syntax
list_name.insert(index,item)

names = ["Cody","Dillan","James","Nick"]
print(names)
# ['Cody', 'Dillan', 'James', 'Nick']

names.insert(0,"Stephanie")

print(names)
# ['Stephanie', 'Cody', 'Dillan', 'James', 'Nick']

Если вы хотите добавить в список более одного элемента, используйте метод .extend().

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

#general syntax
list_name.extend(iterable)

programming_languages = ["Python","JavaScript"]
more_programming_languages = ["Java","C"]

# add more_programming_languages to programming_languages
programming_languages.extend(more_programming_languages) 

print(programming_languages)
# ['Python', 'JavaScript', 'Java', 'C']

Как удалить элементы из списка в Python

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

Один из них – метод .remove(). Он удалит первое вхождение указанного вами элемента.

#general syntax
list_name.remove(item)

programming_languages = ["Python", "JavaScript", "Java", "C"]
print(programming_languages)
# ['Python', 'JavaScript', 'Java', 'C']

programming_languages.remove("Java")
print(programming_languages)
# ['Python', 'JavaScript', 'C']

# deletes only first occurence
programming_languages = ["Python", "JavaScript", "Java", "C","Python"]
programming_languages.remove("Python")
print(programming_languages)
# ['JavaScript', 'Java', 'C', 'Python']

Второй метод — .pop().

Без передачи аргумента он удалит последний элемент в списке.

Также можно передать в pop() в качестве аргумента индекс конкретного элемента, который необходимо удалить.

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

programming_languages = ["Python", "JavaScript", "Java", "C"]

programming_languages.pop()
# 'C'


print(programming_languages)
# ['Python', 'JavaScript', 'Java']

# store returned value in a variable
programming_languages = ["Python", "JavaScript", "Java", "C"]

fave_language = programming_languages.pop(0)
print(fave_language)
# Python

Заключение

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

Повторим, что общего у списков и кортежей:

  • В Python и список, и кортеж считаются объектами .
  • Это контейнеры, используемые для хранения данных. И эти данные могут быть любого типа.
  • Они оба упорядочены и поддерживают этот порядок все время. После определения порядка элементов он не изменится (т.е. не случится такого, что элемент с индексом 4 вдруг станет первым или наоборот).
  • Как в кортежах, так и в списках вы можете получить доступ к отдельным элементам по их индексу.

А чем отличается кортеж от списка? Основное отличие — (не)изменяемость:

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

Спасибо за чтение и успехов в написании кода!

Перевод статьи «Python Tuple VS List – What is the Difference?»