Python: списки vs кортежи

Списки и кортежи хранят один или несколько объектов или значений в определённом порядке. Объекты, хранящиеся в списке или кортеже, могут быть любого типа, включая «пустой» тип, определённый ключевым словом None.

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


Различия в синтаксисе

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

Пример 1.1: создание списка и кортежа

list_num = [1,2,3,4]
tup_num = (1,2,3,4)

print(list_num)
print(tup_num)

Вывод

[1,2,3,4]
(1,2,3,4)

Выше мы определили переменную list_num, которая содержит список чисел от 1 до 4. Список заключён в квадратные скобки []. Также мы определили переменную tup_num, которая содержит кортеж чисел от 1 до 4. Кортеж заключён в круглые скобки ().

В Python есть функция type(), которая возвращает тип созданного объекта.

Пример 1.2: определение типа структуры данных через type()

type(list_num)
type(tup_num)

Вывод

list
tuple

Изменяемый список vs неизменяемый кортеж

Список имеет изменяемую природу, то есть список можно изменить или модифицировать после создания по необходимости. Кортеж же неизменяем — после создания его нельзя изменить.

Пример 2.1: изменение элемента в списке vs в кортеже

list_num[2] = 5
print(list_num)

tup_num[2] = 5

Вывод

[1,2,5,4]
Traceback (most recent call last):
 File "python", line 6, in <module>
TypeError: 'tuple' object does not support item assignment

В приведённом выше коде мы присвоили 5 элементу list_num по индексу 2 и получили 5 по индексу 2 в выводе. Также мы присвоили 5 элементу tup_num по индексу 2 и получили type error. Мы не можем изменить кортеж из-за его неизменяемой природы.

Примечание

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


Доступные операции

У списков больше встроенных функций, чем у кортежей. Мы можем использовать встроенную функцию dir([object]) для получения всех связанных функций для списка и кортежа.

Пример 3.1: директория списка

dir(list_num)

Вывод

['__add__',
'__class__',
'__contains__',
'__delattr__',
'__delitem__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__getitem__',
'__gt__',
'__hash__',
'__iadd__',
'__imul__',
'__init__',
'__init_subclass__',
'__iter__',
'__le__',
'__len__',
'__lt__',
'__mul__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__reversed__',
'__rmul__',
'__setattr__',
'__setitem__',
'__sizeof__',
'__str__',
'__subclasshook__',
'append',
'clear',
'copy',
'count',
'extend',
'index',
'insert',
'pop',
'remove',
'reverse',
'sort']

Пример 3.2: директория кортежа

dir(tup_num)

Вывод

['__add__',
'__class__',
'__contains__',
'__delattr__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__getitem__',
'__getnewargs__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__iter__',
'__le__',
'__len__',
'__lt__',
'__mul__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__rmul__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'count',
'index']

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


Сравнение размера

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

Пример 5.1: вычисление размера списка vs кортежа

a= (1,2,3,4,5,6,7,8,9,0)
b= [1,2,3,4,5,6,7,8,9,0]

print('a=',a.__sizeof__())
print('b=',b.__sizeof__())

Вывод

a= 104
b= 120

В приведённом выше коде у нас есть кортеж a и список b с одинаковыми элементами, но размер кортежа меньше, чем размер списка.


Различные случаи использования

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

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

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

    [('Swordfish', 'Dominic Sena', 2001), ('Snowden', ' Oliver Stone', 2016), ('Taxi Driver', 'Martin Scorsese', 1976)]
    

    В приведённом выше примере есть кортежи внутри списка, который содержит список фильмов.

  3. Чтение данных проще, когда кортежи хранятся внутри списка. Например,

    [(2,4), (5,7), (3,8), (5,9)]
    

    читается проще, чем

    [[2,4], [5,7], [3,8], [5,9]]
    

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

key_val= {('alpha','bravo'):123} # Valid
key_val = {['alpha','bravo']:123} # Invalid

Ключевые моменты для запоминания

  1. Литеральный синтаксис кортежей обозначается круглыми скобками (), а литеральный синтаксис списков — квадратными скобками [].

  2. У списков переменная длина, у кортежей — фиксированная.

  3. Списки изменяемы, кортежи — неизменяемы.

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