Язык программирования Python предоставляет четыре встроенных типа данных для хранения коллекций из объектов. Все они наделены различными свойствами и характеристиками: list
(список), tuple
(кортеж), set
(множество) и dictionary
(словарь).
В статье обсудим различия между списками, кортежами, множествами и словарями, а также поразмышляем, когда лучше использовать каждый из встроенных типов последовательностей Python.
Примечание: поскольку словарь связывает соответствующие значения с ключами, а это совсем другой сценарий использования по сравнению со списками, множествами и кортежами (которые просто содержат значения), словарь не участвует в обсуждении.
Зачем вообще выбирать?
По большей части любая из последовательностей Python применяется на практике без особых проблем, в любом приложении. Однако представьте, что перед вами поставлена легендарная задача найти иголку в стоге сена: какой тип данных Python эффективнее всего справится с такой задачей с точки зрения скорости и памяти?
Может стог сена — это список? Как насчет кортежа? Почему бы не использовать множества всегда? На какие предостережения следует обратить внимание?
Давайте разберёмся.
Отличия между списком, кортежем и множеством
- Отличие 1: дубликаты.
Говоря проще,List
иTuple
в Python как двойняшки разного пола, а тип данныхSet
для них как двоюродный брат. В отличие от списков или кортежей, множество не содержит дубликатов. Другими словами, элементы множества всегда уникальны. Получается, что множество удобно удаляет дубликаты, словно создано именно для этого.
set_example = {1, 1, 2, 3, 3, 3}
# {1, 2, 3}
fruit_set = {'🍎', '🍓', '🍐', '🍎', '🍎', '🍓'}
# {'🍎', '🍐', '🍓'}
- Отличие 2: упорядоченность.
Наверняка вы слышали утверждение “множества и словари в Python не упорядочены”, но на сегодняшний день — это лишь половина правды в зависимости от того, какой версией Python вы пользуетесь. До Python версии 3.6 словари и множества действительно не сохраняли порядок элементов, но начиная с Python 3.7,dictionary
иset
официально упорядочены по времени добавления элементов. А вотlist
иtuple
— это всегда упорядоченные последовательности объектов.
# Пример тогда ещё неупорядоченного множества в Python версии 3.5
fruit_size = {}
>>> fruit_size['🍎'] = 12
>>> fruit_size['🍐'] = 16
>>> fruit_size['🍇'] = 20
>>> fruit_size
{'🍎': 12, '🍇': 20, '🍐': 16}
- Отличие 3: индексация.
Что списки, что кортежи — оба поддерживают индексацию и срезы, а вот множества — нет.
fruit_list = ['🍎', '🍓', '🍐']
fruit_list[1]
# '🍓'
animal_tuple = ('🐶', '🐱', '🐮')
animal_tuple[2]
# '🐮'
vehicle_set = {'🚐', '🏍', '🚗'}
vehicle_set[0]
# TypeError: 'set' object is not subscriptable
Когда выбирать список, а когда — кортеж?
Как упоминалось в руководстве ранее, кортеж — неизменяемый тип данных, тогда как список — изменяемый. Кроме того, размер кортежа фиксированный, а вот размер списка — динамический.
a_tuple = tuple(range(1000))
a_list = list(range(1000))
a_tuple.__sizeof__() # 8024 байта
a_list.__sizeof__() # 9088 байт
- Список подходит, если:
- Последовательность планируется изменять.
- Планируется постепенно добавлять новые элементы в последовательность или удалять старые.
- Кортеж подходит, если:
- Последовательность НЕ планируется изменять.
- Все, что нужно от последовательности — это возможность поочередно перебирать постоянный набор элементов.
- Нужна последовательность элементов для ее назначения в качестве ключа словаря. Поскольку списки — это изменяемый тип данных, их нельзя применять в качестве ключей словаря.
- Важна скорость выполнения операций с последовательностью: из-за отсутствия возможности изменения, кортежи работают куда быстрее списков.
Когда выбирать множества?
Базовая структура типа данных “множество” — это хеш-таблица (Hash Table). Поэтому множества очень быстро справляются с проверкой элементов на вхождение, например содержится ли объект x
в последовательности a_set
.
Идея заключается в том, что поиск элемента в хэш-таблице — это операция O(1), то есть операция с постоянным временем выполнения.
Получается, всегда надо использовать множество?
По сути, если не нужно хранить дубликаты, то множество будет лучшим выбором, чем список.
Выводы
“Преждевременная оптимизация — корень всех зол”.
Итак, самое главное, что вам стоит запомнить по поводу списков, кортежей и множеств.
- Если необходимо хранить дубликаты, то выбирайте список или кортеж.
- Если НЕ планируется изменять последовательность после ее создания, то выбирайте кортеж, а не список.
- Если НЕ нужно хранить дубликаты, то воспользуйтесь множеством, так как они значительно быстрее определяют наличие объекта в последовательности.
В конечном итоге, по большей части не стоит слишком сильно задумываться о том, какого же типа данных последовательностью воспользоваться.
Главное — помнить о похожих чертах и особенностях встроенных типов данных Python.
Читайте также:
- Скрейпинг PDF с нуля на Python: библиотеки tabula-py и Pandas
- Как вычислить миллионное число Фибоначчи на Python
- 3 важных рекомендации Django-программистам
Читайте нас в Telegram, VK и Яндекс.Дзен
Перевод статьи Jerry Ng: Tuples vs. Lists vs. Sets in Python