На этом шаге мы рассмотрим кортежи с точки зрения структур данных.
Кортежи в Python представляют собой простые структуры данных, предназначенные для группирования произвольных объектов.
См. документацию Python "tuple": https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences.
Кортежи неизменяемы - после их создания их нельзя исправить.
С точки зрения производительности кортежи занимают чуть меньше оперативной памяти, чем списки в Python, и к тому же быстрее создаются.
См. CPython: "tupleobject.c"
(https://github.com/python/cpython/blob/master/Objects/tupleobject.c) и
"listobject.c"
(https://github.com/python/cpython/blob/master/Objects/listobject.c).
Как вы видите в приведенном ниже результате дизассемблирования байткода, конструирование кортежной константы занимает всего один код операции LOAD_CONST, в то время как конструирование объекта-списка с одинаковым содержимым требует еще нескольких операций:
>>> import dis >>> dis.dis(compile("(23, 'a', 'b', 'c')", '', 'eval')) 1 0 LOAD_CONST 0 ((23, 'a', 'b', 'c')) 2 RETURN_VALUE >>> dis.dis(compile("[23, 'a', 'b', 'c']", '', 'eval')) 1 0 LOAD_CONST 0 (23) 2 LOAD_CONST 1 ('a') 4 LOAD_CONST 2 ('b') 6 LOAD_CONST 3 ('c') 8 BUILD_LIST 4 10 RETURN_VALUE
Однако вам не стоит особенно налегать на эти различия. На практике разница в производительности часто будет незначительной, и попытка выжать из программы больше эффективности, переключаясь со списков на кортежи, вероятно, будет нерациональной.
Возможным недостатком простых кортежей является то, что данные, которые вы в них храните, извлекаются только путем доступа к кортежу через целочисленные индексы. У вас не получится назначить имена отдельным хранящимся в кортеже свойствам. А это может сказаться на удобочитаемости исходного кода.
Кроме того, кортеж всегда является ситуативной структурой: трудно гарантировать, что у двух кортежей будет одинаковое количество полей и одинаковые хранящиеся в них свойства.
А это - раздолье для ошибок "по недоразумению", например для разночтений порядка следования полей. Поэтому рекомендуем держать минимальное количество полей в кортеже.
# Поля: цвет, пробег, автомат >>> car1 = ('красный', 3812.4, True) >>> car2 = ('синий', 40231.0, False) # Экземпляры кортежа имеют хороший метод repr: >>> car1 ('красный', 3812.4, True) >>> car2 ('синий', 40231.0, False) # Получить пробег: >>> car2[1] 40231.0 # Кортежи неизменяемы: >>> car2[1] = 12 Traceback (most recent call last): . . . . TypeError: 'tuple' object does not support item assignment # Нет защиты от неверных имен полей # или отсутствующих/лишних полей: >>> car3 = (3431.5, 'зеленый', True, 'серебряный') >>> car3 (3431.5, 'зеленый', True, 'серебряный')
На следующем шаге мы рассмотрим использование собственных классов для организации структур данных.