Разница кортежа и списка в Python — основные отличия
В этом уроке вы узнаете разницу между кортежем и списком в Python.
И кортеж, и список являются типами последовательностей. Однако у них есть следующие основные различия.
- 1) Список изменяем, а кортеж — нет
- 2) Эффективность хранения кортежа выше, чем списка
- 3) Копирование кортежа происходит быстрее, чем списка
1) Список изменяем, а кортеж — нет
В следующем примере определяется список и изменяется первый элемент:
fruits = ['apple', 'orange', 'banana'] fruits[0] = 'strawberry' print(fruits)
Выход:
['strawberry', 'orange', 'banana']
Как можно видеть из вывода, вы можете изменить список. Однако вы не можете изменить кортеж. Следующий код приведет к ошибке:
fruits =('apple', 'orange', 'banana') fruits[0] = 'strawberry'
Ошибка:
TypeError: 'tuple' object does not support item assignment
Python не позволяет вам менять элемент кортежа. Но вы можете ссылаться на новый кортеж. Например:
fruits =('apple', 'orange', 'banana') fruits =('strawberry', 'orange', 'banana')
В этом примере Python создает новый кортеж и связывает переменную Fruits с вновь созданным кортежем.
Если вы исследуете адреса памяти объектов-кортежей, вы увидите, что переменная Fruits ссылается на другой адрес памяти после присвоения:
fruits =('apple', 'orange', 'banana') print(hex(id(fruits))) fruits =('strawberry', 'orange', 'banana') print(hex(id(fruits)))
Выход:
0x1c018286e00 0x1c018286e40
2) Эффективность хранения кортежа выше, чем списка
Список изменчив. Это означает, что вы можете добавить к нему больше элементов. Из-за этого Python необходимо выделить для списка больше памяти, чем необходимо. Это называется избыточным распределением. Чрезмерное выделение повышает производительность при расширении списка.
Между тем, кортеж является неизменяемым, поэтому количество его элементов фиксировано. Поэтому Python просто нужно выделить достаточно памяти для хранения исходных элементов. В результате эффективность хранения кортежа выше, чем списка.
Чтобы получить размер объекта, вы используете функцию getsizeof из модуля sys. Ниже показаны размеры списка и кортежа, в котором хранятся одни и те же элементы:
from sys import getsizeof fruits = ['apple', 'orange', 'banana'] print(f'The size of the list is {getsizeof(fruits)} bytes.') fruits =('strawberry', 'orange', 'banana') print(f'The size of the tuple is {getsizeof(fruits)} bytes.')
Выход:
The size of the list is 80 bytes. The size of the tuple is 64 bytes.
3) Копирование кортежа происходит быстрее, чем списка
Когда вы копируете список, Python создает новый список. Следующий пример иллюстрирует копирование списка в другой:
fruit_list = ['apple', 'orange', 'banana'] fruit_list2 = list(fruit_list) print(id(fruit_list) == id(fruit_list2)) # False
Однако при копировании кортежа Python просто повторно использует существующий кортеж. Он не создает новый кортеж, поскольку кортежи неизменяемы.
fruit_tuple =('apple', 'orange', 'banana') fruit_tuple2 = tuple(fruit_tuple) print(id(fruit_tuple) == id(fruit_tuple2)) # True
Поэтому копирование кортежа всегда немного быстрее, чем копирования списка.
Ниже сравнивается время, необходимое для копирования списка и кортежа 1 миллион раз:
from timeit import timeit times = 1_000_000 t1 = timeit("list(['apple', 'orange', 'banana'])", number=times) print(f'Time to copy a list {times} times: {t1}') t2 = timeit("tuple(('apple', 'orange', 'banana'))", number=times) print(f'Time to copy a tuple {times} times: {t2}') diff = "{:.0%}".format((t2 - t1)/t1) print(f'difference: {diff}')