Чем отличаются list, tuple и set? Зачем они нужны?
List (список), tuple (кортеж), set (множество) — это встроенные структуры данных языка python. Каждая из них имеет свои возможности и ограничения. Это позволяет выбрать наиболее подходящий способ хранения информации в программе.
List (список)
Базовая структура данных в python. Элементы в списке хранятся последовательно, каждому из них присвоены индексы, начиная с нуля. В отличие от массива, список может хранить объекты любого типа.
Создание списка
>>> my_list = [] # Создание пустого списка с помощью литерала списка >>> my_list = list() # Создание пустого списка с помощью встроенной функции >>> >>> my_list = [1,2,['a','b'],4,5] # Инициализация списка >>> >>> my_list = list('hello world') # Создание списка из итерируемого объекта >>> my_list ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'] >>> >>> my_list = [x for x in range(10)] # Генератор списков в действии >>> my_list [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Доступные методы
- my_list.append(x) — добавляет x в конец списка
- my_list.clear() — очищает список
- my_list.copy() — возвращает копию списка my_list
- my_list.count(x) — возвращает кол-во элементов со значением x
- my_list.extend(x) — добавляет элементы списка x к концу списка my_list
- my_list.index(x,start,end) — возвращает индекс первого найденного x, можно задать промежуток для поиска (опционально)
- my_list.insert(index, x) — вставляет x на заданную позицию
- my_list.pop(index) — возвращает элемент с указанным индексом и удаляет его, если индекс не указан — возвращается и удаляется последний элемент
- my_list.remove(x) — удаляет первый элемент со значением x
- my_list.reverse() — инвертирует порядок элементов в списке
- my_list.sort(key=x) сортирует список на основе функции x
В каких случаях использовать?
Для хранения элементов, объединенных каким либо признаком. В случае, если изменение элементов и/или расширение списка не предполагается, следует использовать неизменяемый аналог — кортеж.
Tuple (кортёж)
Кортеж — это неизменяемый и более быстрый аналог списка. Он защищает хранимые данные от непреднамеренных изменений и может использоваться в качестве ключа в словарях (словарь — ассоциативный массив в python).
Создание кортежа.
>>> my_tuple = () # Создание кортежа с помощью литерала >>> my_tuple = tuple() # Создание кортежа с помощью встроенной функции >>> >>> my_tuple = (1,2,['a','b'],4,5) # Инициализация кортежа >>> >>> my_tuple = tuple('hello world') # Создание кортежа из итерируемого объекта >>> my_tuple ('h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd') >>> >>> my_tuple = tuple(2**x for x in [0, 1, 2, 3]) # Генератор кортежей >>> my_tuple (1, 2, 4, 8)
Доступные методы
- my_tuple.count(x) — возвращает кол-во элементов со значением x
- my_tuple.index(x,start,end) — возвращает индекс первого найденного x, можно задать промежуток для поиска (опционально)
В каких случаях использовать?
Для хранения данных вместо списка (если они не предполагают изменений).
Set (множество)
Множество — это набор уникальных элементов в случайном порядке (неупорядоченный список). Множества примечательны тем, что операция проверки “принадлежит ли объект множеству” происходит значительно быстрее аналогичных операций в других структурах данных.
Создание множества
>>> my_something = > # . Попытка создать множество при помощи литерала даст нам словарь >>> type(my_something) class 'dict'> >>> >>> my_set = set() # Создание при помощи встроенной функции >>> >>> my_set = 1,2,3,4,5> # Инициализация множества >>> >>> my_set = set('hello world') # Создания множества из итерируемого объекта >>> my_set 'r', 'o', 'e', 'h', 'd', 'w', 'l', ' '> >>> >>> my_set = x for x in range(10)> # Генератор множеств >>> my_set 0, 1, 2, 3, 4, 5, 6, 7, 8, 9>
Доступные методы
- my_set.add(x) — добавляет x во множество
- my_set.difference(x) — возвращает множество элементов my_set, которые не входят во множество x
- my_set.difference_update(x) — удаляет из множества my_set все элементы, которые входят во множество x
- my_set.discard(x) — удаляет элемент x из my_set
- my_set.intersection(x) — возвращает элементы общие для множеств my_set и x
- my_set.intersection_update(x) — удаляет из множества my_set элементы, которых нет во множестве x
- my_set.isdisjoint(x) — возвращает true если my_set и x не содержат одинаковых значений
- my_set.issubset(x) — возвращает true если все элементы my_set входят во множество x
- my_set.issuperset(x) — возвращает true если все элементы x входят во множество my_set
- my_set.pop() — возвращает и удаляет первый (на данный момент) элемент множества
- my_set.remove(x) — удаляет x из множества
- my_set.symmetric_difference(x) — возвращает все элементы из x и my_set, которые встречаются только в одном из множеств
- my_set.symmetric_difference_update(x) — обновляет исходное множество таким образом, что оно будет состоять из всех элементов x и my_set, которые встречаются только в одном из множеств
- my_set.union(x) — возвращает новое множество, состоящее из всех элементов x и my_set
- my_set.update(x) — добавляет в my_set все элементы x
В каких случаях использовать?
Когда необходимо проверять принадлежит ли значение набору уникальных элементов и отсутствует необходимость поддерживать порядок в данном наборе.
Попробуйте бесплатные уроки по Python
Получите крутое код-ревью от практикующих программистов с разбором ошибок и рекомендациями, на что обратить внимание — бесплатно.
Переходите на страницу учебных модулей «Девмана» и выбирайте тему.
Списки (List) vs Кортежи (Typle)
Списки и кортежи используются для последовательного хранения одного или нескольких объектов или типов данных Python. И те и другие могут хранить любые данные, такие как целые числа, плавающие числа, строки и словари. Списки и кортежи похожи по большинству параметров, но здесь мы опишем основные различия между ними.
Различия в представлении
Представление списков и кортежей отличается незначительно. Списки обычно заключаются в квадратную скобку ё [] , а элементы — через запятую. Кортежи заключаются в круглую скобку () , а элементы разделяются запятой. Скобки использовать необязательно, и такие типы кортежей называются упаковкой кортежей.
Рассмотрим следующий пример.
list1 = ['JavaTpoint', 1, 2, 54.30, ] print(type(list)) tuple1 = ('JavaTpoint',5,8,31.9,[1,2,3]) print(type(tuple1))
В приведенной выше программе мы определили переменную list1 , которая содержит список данных разного типа с индексом от 0 до 4 . Мы определили еще одну переменную tuple1 , которая содержит кортеж данных разного типа. Она заключена в рамку () .
Изменяемые списки и неизменяемые кортежи в Python
Это самое важное различие между списком и кортежем, в то время как списки являются изменяемыми, а кортежи — неизменяемыми. Списки являются изменяемыми, что означает, что объект Python может быть изменен после создания, в то время как кортежи не могут быть изменены после создания. Рассмотрим приведенный пример.
a = ["Peter","Joseph","Mathew","Ricky"] print(a)
['Peter', 'Joseph', 'Mathew', 'Ricky']
Теперь мы меняем 0-й элемент индекса «Peter» на «Samson».
a[0] = "Samson" print(a)
['Samson', 'Joseph', 'Mathew', 'Ricky']
Теперь мы создаем кортеж и делаем то же самое.
a = (10,20,"JavaTpoint",30,40) print(a)
(10, 20, 'JavaTpoint', 30, 40)
a[0] = 50
TypeError Traceback (most recent call last) in ----> 1 a[0] = 50 TypeError: 'tuple' object does not support item assignment
Мы получаем ошибку при изменении 1-го элемента кортежа из-за неизменяемости. Он не поддерживает присвоение элементов.
Отладка кортежей и списков в Python
Кортежи легко отлаживать в большом проекте из-за их неизменяемости. Если у нас небольшой проект или меньшее количество данных, то списки играют эффективную роль. Рассмотрим следующий пример:
a = [6,9,4,3,7,0,1] # Copying address of a in b b = a a[3] = "JavaToint" print(a)
[6, 9, 4, 'JavaToint', 7, 0, 1]
В приведенном выше коде мы сделали b = a ; здесь мы не копируем объект списка из b в a . b ссылается на адрес списка a . Это означает, что если мы сделаем изменение в b , то это отразится так же, как и в списке a , и это облегчает отладку. Но это сложно для серьезного проекта, где объекты Python могут иметь множество ссылок.
Будет сложно отслеживать эти изменения в списках, но неизменяемый объект кортежа не может измениться после создания. Поэтому кортежи легче отлаживать.
Поддержка функций у кортежей и списков в Python
Кортежи поддерживают меньше операций, чем списки. Встроенный dir(object) используется для получения всех поддерживаемых функций для списка и кортежа.
Функциии списков (List)
dir(list)
['__add__','__class__','__contains__','__delattr__','__delitem__','__dir_, '__doc__','__eq__','__format__', '__get__','__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']
Функциии кортежей (Tuple)
['__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']
Расходование памяти у списков (List) и у кортежей (Tuple) в Python
Кортежи более эффективны с точки зрения использования памяти, чем списки, поскольку кортеж имеет меньше встроенных операций. Списки подходят для работы с небольшим количеством элементов, в то время как кортежи немного быстрее, чем списки, для работы с огромным количеством данных.
Tuple = (1,2,3,4,5,6,7,8,9,0,5485,87525,955,3343,53234,6423,623456,234535) List = [1,2,3,4,5,6,7,8,9,0,78,34,43,32,43,55,54,212,642,533,43434,54532 ] print('Tuple size =', Tuple.__sizeof__()) # Tuple size = 52 print('List size =', List.__sizeof__())
Tuple size = 168 List size = 216
В некоторых случаях списки могут показаться более полезными, чем кортежи. Но кортежи являются важными структурами данных в Python. Кортежи обычно используются для неизменяемых данных, или можно сказать, что данные в кортежах «защищены от записи». Кортежи передают интерпретатору Python указание на то, что данные не должны меняться в будущем. Мы можем использовать кортеж так же, как и словарь, не используя ключи для хранения данных, например:
list1 = [(101, "Mike", 24),(102, 'Hussey', 26),(103, 'David', 27),(104, 'Warner', 29)]
Кортежи могут использовать ключи словаря, поскольку они хэшируемы и неизменяемы, в то время как списки не могут использовать ключи словаря.
dict = #valid dictionary dict = #Invalid dictionary
Списки и кортежи в Python для начинающих
Предположим, что вы составляете список гостей на свадьбу. Этот список постоянно меняется: добавились друзья семьи Дима и Света, не смогут прийти троюродные сестры со стороны жены Лида с Наташей.
Для представления таких данных из реального мира в Python отлично подходят списки. Списки — это еще один встроенный тип данных Python.
Создать, или другими словами, объявить список в Python можно двумя способами, так:
my_list = list()
my_list = []
Вернемся, однако, к гостям на свадьбе. Для создания списка гостей, сразу же при создании помещаем внутрь скобок строки с именами через запятую.
guests = ['Родители', 'Одноклассники', 'Лида и Наташа']print(guests)
Операции с элементами списка ¶
В нашем списке три элемента: «Родители», «Одноклассники», «Лида и Наташа», — которые хранятся внутри списка именно в таком порядке. Если только вы не измените порядок списка, «Родители» всегда будет первым элементом, «Одноклассники» — вторым и «Лида и Наташа» — третьим. Родители представляет собой начало списка, а Лида и Наташа — конец. Мы помним, что Лида и Наташа не смогут прийти, и их нужно удалить из списка.
С помощью метода remove можно удалить последний элемент в списке.
guests = ['Родители', 'Одноклассники', 'Лида и Наташа']print(guests) # ['Родители', 'Одноклассники', 'Лида и Наташа']guests.remove("Лида и Наташа")print(guests) # ['Родители', 'Одноклассники', 'Лида и Наташа']
Но не забываем, нужно еще добавить в список двух гостей. Добавление новых элементов в конец списка происходит при помощи метода append .
guests = ['Родители', 'Одноклассники', 'Лида и Наташа']print(guests) # ['Родители', 'Одноклассники', 'Лида и Наташа']guests.remove("Лида и Наташа")print(guests) # ['Родители', 'Одноклассники']guests.append('Дима')guests.append('Света')print(guests) # ['Родители', 'Одноклассники', 'Дима', 'Света']
В список можно не только добавить элемент, но и изменить одно из его значений на другое, согласно индексу элемента.
guests = ['Родители', 'Одноклассники', 'Дима', 'Света']print(guests) # ['Родители', 'Одноклассники', 'Лида и Наташа']guests[2] = 'Коллеги'print(guests) # ['Родители', 'Одноклассники', 'Коллеги', 'Света']
И так, список — это контейнер, хранящий объекты в определенном порядке. Обратите внимание, что в отличие от строк, методы списка меняют исходный список. Есть однако у списков кое‑что общее со строками. Это доступ к элементу по индексу и срезы. Все это работает в списках точно так же, как и в строках.
guests = ['Родители', 'Одноклассники', 'Дима', 'Света']print(guests[0]) # Родителиprint(guests[-1]) # Светаprint(guests[:2]) # ['Родители', 'Одноклассники']
Кортежи ¶
Кортежи — это контейнеры, хранящие объекты в определенном порядке. В отличие от списков, кортежи неизменяемы.
Как только вы создали кортеж, значение какого-либо его элемента уже нельзя изменить, как нельзя добавлять и удалять элементы. Кортежи объявляются с помощью круглых скобок. Элементы в кортеже должны быть разделены запятыми.
Для создания кортежей также используют один из двух вариантов синтаксиса. Первый:
my_tuple = tuple()
my_tuple = ()
Чтобы добавить в кортеж новые объекты, создайте его вторым способом, указав через запятую каждый желаемый элемент.
data = ('И. Иванов', 1958, True)print(data) # ('И. Иванов', 1958, True)
Даже если кортеж содержит только один элемент, после этого элемента все равно нужно поставить запятую. Таким образом Python отличает кортеж от числа в скобках, определяющих порядок выполнения операций.
Получить элементы кортежа можно так же, как и элементы списка, указывая индекс элемента.
books = ("1984", "О дивный новый мир", "451 градус по Фаренгейту")print(books[2]) # 451 градус по Фаренгейту
Ключевое слово in / not in ¶
Проверить, содержится ли элемент в кортеже, можно с помощью ключевого слова in .
books = ("1984", "О дивный новый мир", "451 градус по Фаренгейту")print("1984" in books) # Trueprint("Незнайка на луне" in books) # False
Поместите перед in ключевое слово not для проверки отсутствия элемента в кортеже.
books = ("1984", "О дивный новый мир", "451 градус по Фаренгейту")print("Незнайка на луне" not in books) # True
Те же операции с ключевыми словами in и not in сработают и со списками.
Сложение кортежей и списков ¶
При помощи оператора сложения можно соединять друг с другом две одинаковые структуры данных. Пример ниже со списками также будет работать и с кортежами:
colors1 = ["синий", "зеленый", "желтый"]colors2 = ["оранжевый", "розовый", "черный"]print(colors1 + colors2) # ['синий', 'зеленый', 'желтый', 'оранжевый', 'розовый', 'черный']
На данном этапе вам может стать интересно, зачем использовать структуры данных, которые кажутся менее гибкими, чем списки? На самом же деле, кортежи удобны, когда вы имеете дело со значениями, которые никогда не изменятся. Примером таких данных для кортежа могут быть географические координаты. Долготу и широту города следует сохранить в кортеже, поскольку эти значения никогда не изменятся, а сохранение в кортеже будет гарантировать, что другие части программы случайно их не изменят.
Итерирование ¶
Строки, списки и кортежи поддерживают итерирование (программа может их перебирать, значение за значением), то есть к каждому их элементу можно получить доступ через цикл — такие объекты называются итерируемыми. Каждый элемент в итерируемом объекте, как мы уже знаем, имеет свой порядковый индекс.
В следующем примере элемент Москва записан в списке с индексом 0, Хельсинки с индексом 1, а ‘Анкара’ с индексом 2.
cities = ['Москва', 'Хельсинки' ,'Анкара']for city in cities: print(city) # Москва# Хельсинки# Анкара
Вот мы и познакомились с оператором for — циклом, перебирающим итерируемый объект. Цикл for можно использовать, чтобы определять инструкции, которые будут выполняться один раз для каждого элемента в итерируемом объекте, и с помощью таких инструкций вы можете получать доступ ко всем этим элементам и осуществлять операции с ними.
Например, с помощью цикла for , выполняющего перебор списка строк, и метода upper можно сделать символы каждой строки прописными:
cities = ['Москва', 'Хельсинки' ,'Анкара']for city in cities: print(city.upper()) # МОСКВА# ХЕЛЬСИНКИ# АНКАРА
Как показано в примерах выше, цикл for определяется синтаксисом: for имя_переменной in имя_итерируемого_объекта: где имя_переменной — выбранное вами имя переменной, в которую каждую итерацию цикла будет записываться очередное значение из итерируемого объекта.
Python для начинающих: какая разница между tuple, list и set?
Язык программирования Python предоставляет четыре встроенных типа данных для хранения коллекций из объектов. Все они наделены различными свойствами и характеристиками: list (список), tuple (кортеж), set (множество) и dictionary (словарь).
В статье обсудим различия между списками, кортежами, множествами и словарями, а также поразмышляем, когда лучше использовать каждый из встроенных типов последовательностей Python.
Примечание: поскольку словарь связывает соответствующие значения с ключами, а это совсем другой сценарий использования по сравнению со списками, множествами и кортежами (которые просто содержат значения), словарь не участвует в обсуждении.
Зачем вообще выбирать?
По большей части любая из последовательностей Python применяется на практике без особых проблем, в любом приложении. Однако представьте, что перед вами поставлена легендарная задача найти иголку в стоге сена: какой тип данных Python эффективнее всего справится с такой задачей с точки зрения скорости и памяти?
Может стог сена — это список? Как насчет кортежа? Почему бы не использовать множества всегда? На какие предостережения следует обратить внимание?
Отличия между списком, кортежем и множеством
- Отличие 1: дубликаты.
Говоря проще, List и Tuple в Python как двойняшки разного пола, а тип данных Set для них как двоюродный брат. В отличие от списков или кортежей, множество не содержит дубликатов. Другими словами, элементы множества всегда уникальны. Получается, что множество удобно удаляет дубликаты, словно создано именно для этого.
set_example =
# fruit_set =
#
- Отличие 2: упорядоченность.
Наверняка вы слышали утверждение “множества и словари в Python не упорядочены”, но на сегодняшний день — это лишь половина правды в зависимости от того, какой версией Python вы пользуетесь. До Python версии 3.6 словари и множества действительно не сохраняли порядок элементов, но начиная с Python 3.7, dictionary и set официально упорядочены по времени добавления элементов. А вот list и tuple — это всегда упорядоченные последовательности объектов.
# Пример тогда ещё неупорядоченного множества в Python версии 3.5fruit_size = <>
>>> fruit_size[''] = 12
>>> fruit_size[''] = 16
>>> fruit_size[''] = 20
>>> fruit_size
- Отличие 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-программистам