Списки в Python: что это такое и как с ними работать
Рассказали всё самое важное о списках для тех, кто только становится «змееустом».
Иллюстрация: Оля Ежак для Skillbox Media
Сегодня мы подробно поговорим о, пожалуй, самых важных объектах в Python — списках. Разберём, зачем они нужны, как их использовать и какие удобные функции есть для работы с ними.
В статье есть всё, что начинающим разработчикам нужно знать о списках в Python:
- Что это такое
- Как создавать списки в Python
- Какие с ними можно выполнять операции
- Как работать со встроенными функциями
- Какие в Python есть методы управления элементами
Что такое списки
Список (list) — это упорядоченный набор элементов, каждый из которых имеет свой номер, или индекс, позволяющий быстро получить к нему доступ. Нумерация элементов в списке начинается с 0: почему-то так сложилось в C, а C — это база. Теорий на этот счёт много — на «Хабре» даже вышло большое расследование :)
В одном списке одновременно могут лежать данные разных типов — например, и строки, и числа. А ещё в один список можно положить другой и ничего не сломается:
Все элементы в списке пронумерованы. Мы можем без проблем узнать индекс элемента и обратиться по нему.
Списки называют динамическими структурами данных, потому что их можно менять на ходу: удалить один или несколько элементов, заменить или добавить новые.
Когда мы создаём объект list, в памяти компьютера под него резервируется место. Нам не нужно переживать о том, сколько выделяется места и когда оно освобождается, — Python всё сделает сам. Например, когда мы добавляем новые элементы, он выделяет память, а когда удаляем старые — освобождает.
Под капотом списков в Python лежит структура данных под названием «массив». У массива есть два важных свойства: под каждый элемент он резервирует одинаковое количество памяти, а все элементы следуют друг за другом, без «пробелов».
Однако в списках Python можно хранить объекты разного размера и типа. Более того, размер массива ограничен, а размер списка в Python — нет. Но всё равно мы знаем, сколько у нас элементов, а значит, можем обратиться к любому из них с помощью индексов.
И тут есть небольшой трюк: списки в Python представляют собой массив ссылок. Да-да, решение очень элегантное — каждый элемент такого массива хранит не сами данные, а ссылку на их расположение в памяти компьютера!
Как создать список в Python
Чтобы создать объект list, в Python используют квадратные скобки — []. Внутри них перечисляют элементы через запятую:
Мы создали список a и поместили в него три числа, которые разделили запятыми. Давайте выведем его с помощью функции print():
Python выводит элементы в квадратных скобках, чтобы показать, что это list, а также ставит запятые между элементами.
Мы уже говорили, что списки могут хранить данные любого типа. В примере ниже объект b хранит: строку — cat, число — 123 и булево значение — True:
Также в Python можно создавать вложенные списки:
Мы получили объект, состоящий из двух чисел — 1 и 2 — и вложенного list с двумя элементами — [3, 4].
Читайте также:
Операции со списками
Если просто хранить данные в списках, то от них будет мало толку. Поэтому давайте рассмотрим, какие операции они позволяют выполнить.
Индексация
Доступ к элементам списка получают по индексам, через квадратные скобки []:
Мы обратились ко второму элементу и вывели его с помощью print().
Здесь важно помнить две вещи:
- у каждого элемента есть свой индекс;
- индексы начинаются с 0.
Давайте ещё поиграем с индексами:
В последней строке мы обратились к несуществующему индексу, поэтому Python выдал ошибку.
Кроме того, Python поддерживает обращение к нескольким элементам сразу — через интервал. Делается это с помощью двоеточия — :.
Двоеточие позволяет получить срез списка. Полная форма оператора выглядит так: начальный_индекс:конечный_индекс:шаг.
Здесь мы указываем, с какого индекса начинается «срез», на каком заканчивается и с каким шагом берутся элементы — по умолчанию 1. Единственный нюанс с конечным индексом: хоть мы и можем подумать, что закончим именно на нём, на самом деле Python остановится на элементе с индексом конечный_индекс — 1. Почему создатели языка решили так сделать? Кто их знает.
В примере выше мы начали с индекса 0, а закончили на 1, потому что последний индекс не включается. Наш шаг был 1, то есть мы прошлись по каждому элементу.
Усложним пример:
Здесь мы шли по элементам с шагом 2. Начали с индекса 1 — это первое число внутри скобок, а закончили на индексе 6, не включая его. Двигались с шагом 2, то есть через один элемент, и получили [2, 4].
Протестируйте этот тип индексации сами, чтобы лучше понять, как работают срезы в Python.
Изменение элементов
Списки — это динамическая структура данных. А значит, мы можем менять их уже после создания.
Например, можно заменить один элемент на другой:
Мы обратились к элементу по индексу и заменили его на число 4. Всё прошло успешно, список изменился.
Но нужно быть осторожными, потому что может случиться такое:
Сначала мы создали список a с двумя элементами — 1 и 2. Затем объявили переменную b и присвоили ей содержимое a. Потом заменили первый элемент в a и… удивились, что он заменился и в b.
Проблема в том, что a — это ссылка на область в памяти компьютера, где хранится первый элемент списка, а также на следующий его элемент. Вот как всё это устроено в памяти компьютера:
Каждый элемент списка имеет четыре секции: свой адрес, данные, адрес следующего элемента и адрес предыдущего. Если мы получили доступ к какому-то элементу, мы без проблем можем двигаться вперёд-назад по этому списку и менять его данные.
Поэтому, когда мы присвоили списку b список a, то на самом деле присвоили ему ссылку на первый элемент — по сути, сделав их одним списком.
Объединение списков
Иногда полезно объединить два списка. Чтобы это сделать, используют оператор +:
Мы создали два списка — a и b. Затем переприсвоили a новым списком, который стал объединением старого a и b.
Разложение списка
Элементы списка можно присвоить отдельным переменным:
Здесь из списка a поочерёдно достаются элементы, начиная с индекса 0, и присваиваются переменным. И в отличие от присвоения одного списка другому, в этом случае Python создаст три отдельных целых числа, которые никак не будут связаны с элементами списка, и присвоит их трём переменным. Поэтому, если мы изменим, например, переменную d2, со списком a ничего не случится.
Перебор элементов
Мы можем перебирать элементы списка с помощью циклов for и while.
Так выглядит перебор через for:
Здесь мы перебираем каждый элемент списка и выводим их с помощью функции print().
А вот так выглядит перебор через цикл while:
Этот перебор чуть сложнее, потому что мы используем дополнительную переменную i, чтобы обращаться к элементам списка. Также мы использовали встроенную функцию len(), чтобы узнать размер нашего списка. А ещё в условии цикла while мы указали знак «меньше» (<), потому что индексация элементов идёт до значения количество элементов списка — 1. Как и в прошлом примере, все элементы по очереди выводятся с помощью функции print().
Сравнение списков
Python поддерживает сравнение списков. Два списка считаются равными, если они содержат одинаковые элементы. Функция возвращает булево значение — True или False:
Получили, что списки равны.
В некоторых языках равенство ещё проверяется и по тому, ссылаются ли переменные на один и тот же объект. Обычно это делается через оператор ===. В Python это можно сделать через оператор is, который проверяет, имеют ли две переменные один и тот же адрес в памяти:
Получили, что две переменные ссылаются на один и тот же адрес в памяти.
Встроенные функции для списков Python
В Python есть четыре функции, которые позволяют узнавать длину списка, сортировать его и возвращать максимальное и минимальное значение.
len()
Возвращает длину списка:
sorted()
Возвращает отсортированный список:
min() и max()
Возвращают наименьший и наибольший элемент списка:
Методы списков Python
Чтобы проще управлять элементами списка, в стандартной библиотеке Python есть набор популярных методов для списков. Разберём основные из них.
append()
Добавляет новый элемент в конец списка:
extend()
Добавляет набор элементов в конец списка:
Внутрь метода extend() нужно передать итерируемый объект — например, другой list или строку.
Вот так метод extend() добавит строку:
Заметьте, что строка добавилась посимвольно.
insert()
Добавляет новый элемент по индексу:
Сначала мы передаём индекс, по которому хотим вставить новый элемент, а затем сам элемент.
remove()
Удаляет элемент из списка:
Метод удаляет только первое вхождение элемента. Остальные остаются нетронутыми.
Если элемента нет в списке, Python вернёт ошибку и программа прервётся:
Ошибка говорит, что элемента нет в списке.
Читайте также:
clear()
Удаляет все элементы из списка и делает его пустым:
index()
Возвращает индекс элемента списка в Python:
Если элемента нет в списке, выведется ошибка:
pop()
Удаляет элемент по индексу и возвращает его как результат:
Мы не передали индекс в метод, поэтому он удалил последний элемент списка. Если передать индекс, то получится так:
count()
Считает, сколько раз элемент повторяется в списке:
sort()
Сортирует список:
Если нам нужно отсортировать в обратном порядке — от большего к меньшему, — в методе есть дополнительный параметр reverse:
reverse()
Переставляет элементы в обратном порядке:
copy()
Копирует список:
Для того чтобы быстро находить нужные методы во время работы, пользуйтесь этой шпаргалкой:
Метод | Что делает |
---|---|
a.append(x) | Добавляет элемент x в конец списка a. Если x — список, то он появится в a как вложенный |
a.extend(b) | Добавляет в конец a все элементы списка b |
a.insert(i, x) | Вставляет элемент x на позицию i |
a.remove(x) | Удаляет в a первый элемент, значение которого равно x |
a.clear() | Удаляет все элементы из списка a и делает его пустым |
a.index(x) | Возвращает индекс элемента списка |
a.pop(i) | Удаляет элемент по индексу и возвращает его |
a.count(x) | Считает, сколько раз элемент повторяется в списке |
a.sort() | Сортирует список. Чтобы отсортировать элементы в обратном порядке, нужно установить дополнительный аргумент reverse=True |
a.reverse() | Возвращает обратный итератор списка a |
a.copy() | Создаёт поверхностную копию списка. Для создания глубокой копии используйте метод deepcopy из модуля copy |
Что запомнить
Лучше не учить это всё, а применять на практике. А ещё лучше — попытаться написать каждый метод самостоятельно, не используя никакие встроенные функции.
Сколько бы вы ни писали код на Python, всё равно придётся подсматривать в документацию и понимать, какой метод что делает. И для этого есть разные удобные сайты — например, полный список методов можно посмотреть на W3Schools.
Больше интересного про код в нашем телеграм-канале. Подписывайтесь!