Списки в Python: что это такое и как с ними работать
Рассказали всё самое важное о списках для тех, кто только становится «змееустом».
Сегодня мы подробно поговорим о, пожалуй, самых важных объектах в Python — списках. Разберём, зачем они нужны, как их использовать и какие удобные функции есть для работы с ними.
В статье есть всё, что начинающим разработчикам нужно знать о списках в Python:
- Что это такое
- Как создавать списки в Python
- Какие с ними можно выполнять операции
- Как работать со встроенными функциями
- Какие в Python есть методы управления элементами
Что такое списки
Список (list) — это упорядоченный набор элементов, каждый из которых имеет свой номер, или индекс, позволяющий быстро получить к нему доступ. Нумерация элементов в списке начинается с 0: почему-то так сложилось в C, а C — это база. Теорий на этот счёт много — на «Хабре» даже вышло большое расследование :)

Иллюстрация: Оля Ежак для Skillbox Media
В одном списке одновременно могут лежать данные разных типов — например, и строки, и числа. А ещё в один список можно положить другой и ничего не сломается:

Иллюстрация: Оля Ежак для Skillbox Media
Все элементы в списке пронумерованы. Мы можем без проблем узнать индекс элемента и обратиться по нему.
Списки называют динамическими структурами данных, потому что их можно менять на ходу: удалить один или несколько элементов, заменить или добавить новые.

Иллюстрация: Оля Ежак для Skillbox Media
Когда мы создаём объект list, в памяти компьютера под него резервируется место. Нам не нужно переживать о том, сколько выделяется места и когда оно освобождается, — Python всё сделает сам. Например, когда мы добавляем новые элементы, он выделяет память, а когда удаляем старые — освобождает.
Под капотом списков в Python лежит структура данных под названием «массив». У массива есть два важных свойства: под каждый элемент он резервирует одинаковое количество памяти, а все элементы следуют друг за другом, без «пробелов».
Однако в списках Python можно хранить объекты разного размера и типа. Более того, размер массива ограничен, а размер списка в Python — нет. Но всё равно мы знаем, сколько у нас элементов, а значит, можем обратиться к любому из них с помощью индексов.
И тут есть небольшой трюк: списки в Python представляют собой массив ссылок. Да-да, решение очень элегантное — каждый элемент такого массива хранит не сами данные, а ссылку на их расположение в памяти компьютера!
Как создать список в Python
Чтобы создать объект list, в Python используют квадратные скобки — []. Внутри них перечисляют элементы через запятую:
a = [1, 2, 3]Мы создали список a и поместили в него три числа, которые разделили запятыми. Давайте выведем его с помощью функции print():
print(a) # [1, 2, 3]Python выводит элементы в квадратных скобках, чтобы показать, что это list, а также ставит запятые между элементами.
Мы уже говорили, что списки могут хранить данные любого типа. В примере ниже объект b хранит: строку — cat, число — 123 и булево значение — True:
b = ['cat', 123, True]
print(b) # ['cat', 123, True]Также в Python можно создавать вложенные списки:
c = [1, 2, [3, 4]]
print(c) # [1, 2, [3, 4]]Мы получили объект, состоящий из двух чисел — 1 и 2 — и вложенного list с двумя элементами — [3, 4].
Читайте также:
Операции со списками
Если просто хранить данные в списках, то от них будет мало толку. Поэтому давайте рассмотрим, какие операции они позволяют выполнить.
Индексация
Доступ к элементам списка получают по индексам, через квадратные скобки []:
a = [1, 2, 3]
print(a[1]) # 2Мы обратились ко второму элементу и вывели его с помощью print().
Здесь важно помнить две вещи:
- у каждого элемента есть свой индекс;
- индексы начинаются с 0.
Давайте ещё поиграем с индексами:
a = [1, 2, 3, 4]
a[0] # Обратится к 1
a[2] # Обратится к 3
a[3] # Обратится к 4
a[4] # Выведет ошибкуВ последней строке мы обратились к несуществующему индексу, поэтому Python выдал ошибку.
Кроме того, Python поддерживает обращение к нескольким элементам сразу — через интервал. Делается это с помощью двоеточия — :.
a = [1, 2, 3, 4]
a[0:2] # Получим [1, 2]Двоеточие позволяет получить срез списка. Полная форма оператора выглядит так: начальный_индекс: конечный_индекс: шаг.
Здесь мы указываем, с какого индекса начинается «срез», на каком заканчивается и с каким шагом берутся элементы — по умолчанию 1. Единственный нюанс с конечным индексом: хоть мы и можем подумать, что закончим именно на нём, на самом деле Python остановится на элементе с индексом конечный_индекс — 1. Почему создатели языка решили так сделать? Кто их знает.
В примере выше мы начали с индекса 0, а закончили на 1, потому что последний индекс не включается. Наш шаг был 1, то есть мы прошлись по каждому элементу.
Усложним пример:
a = [1, 2, 3, 4, 5]
a[1:6:2] # Получим [2, 4]Здесь мы шли по элементам с шагом 2. Начали с индекса 1 — это первое число внутри скобок, а закончили на индексе 6, не включая его. Двигались с шагом 2, то есть через один элемент, и получили [2, 4].
Протестируйте этот тип индексации сами, чтобы лучше понять, как работают срезы в Python.
Изменение элементов
Списки — это динамическая структура данных. А значит, мы можем менять их уже после создания.
Например, можно заменить один элемент на другой:
a = [1, 2, 3]
a[1] = 4
print(a) # [1, 4, 3]Мы обратились к элементу по индексу и заменили его на число 4. Всё прошло успешно, список изменился.
Но нужно быть осторожными, потому что может случиться такое:
a = [1, 2]
b = a
a[0] = 5
print(a) # [5, 2]
print(b) # [5, 2]Сначала мы создали список a с двумя элементами — 1 и 2. Затем объявили переменную b и присвоили ей содержимое a. Потом заменили первый элемент в a и… удивились, что он заменился и в b.
Проблема в том, что a — это ссылка на область в памяти компьютера, где хранится первый элемент списка, а также на следующий его элемент. Вот как всё это устроено в памяти компьютера:

Иллюстрация: Оля Ежак для Skillbox Media
Каждый элемент списка имеет четыре секции: свой адрес, данные, адрес следующего элемента и адрес предыдущего. Если мы получили доступ к какому-то элементу, мы без проблем можем двигаться вперёд-назад по этому списку и менять его данные.
Поэтому, когда мы присвоили списку b список a, то на самом деле присвоили ему ссылку на первый элемент — по сути, сделав их одним списком.

Читайте также:
Объединение списков
Иногда полезно объединить два списка. Чтобы это сделать, используют оператор +:
a = [1, 2]
b = [3, 4]
с = a + b
print(с) # [1, 2, 3, 4]Мы создали два списка — a и b. Затем переприсвоили a новым списком, который стал объединением старого a и b.
Разложение списка
Элементы списка можно присвоить отдельным переменным:
a = [1, 2, 3]
d1, d2, d3 = a
print(d1) # 1
print(d2) # 2
print(d3) # 3Здесь из списка a поочерёдно достаются элементы, начиная с индекса 0, и присваиваются переменным. И в отличие от присвоения одного списка другому, в этом случае Python создаст три отдельных целых числа, которые никак не будут связаны с элементами списка, и присвоит их трём переменным. Поэтому, если мы изменим, например, переменную d2, со списком a ничего не случится.
Перебор элементов
Мы можем перебирать элементы списка с помощью циклов for и while.
Так выглядит перебор через for:
animals = ['cat', 'dog', 'bat']
for animal in animals:
print(animal) # cat dog batЗдесь мы перебираем каждый элемент списка и выводим их с помощью функции print().
А вот так выглядит перебор через цикл while:
animals = ['cat', 'dog', 'bat']
i = 0
while i < len(animals):
print(animals[i]) # cat dog bat
i += 1Этот перебор чуть сложнее, потому что мы используем дополнительную переменную i, чтобы обращаться к элементам списка. Также мы использовали встроенную функцию len(), чтобы узнать размер нашего списка. А ещё в условии цикла while мы указали знак «меньше» (<), потому что индексация элементов идёт до значения количество элементов списка — 1. Как и в прошлом примере, все элементы по очереди выводятся с помощью функции print().
Генераторы списков
Если вам нужно получить набор значений по понятному правилу, удобно использовать генераторы списков. Это короткая запись, которая проходит по данным и сразу создаёт новый список из преобразованных или отфильтрованных значений. Генератор делает то же самое, что и обычный цикл, но компактнее, к тому же читается легче — а значит, будет меньше ошибок.
Генератор списка состоит из двух частей: выражения, которое определяет преобразование каждого элемента, и источника данных с циклом for для итерации. Общий синтаксис: [выражение for элемент in источник].
result = [x * 2 for x in range(1,9)]
print(result) # [2, 4, 6, 8, 10, 12, 14, 16]В примере выше мы перебираем числа от 1 до 8 (range(1, 9) не включает 9), умножаем каждое на 2 и помещаем результаты в новый список result.
Чтобы дополнительно отфильтровать данные, добавьте условие прямо в выражение. Например, сформируем список только из нечётных чисел:
result = [x for x in range(1, 10) if x % 2 == 1]
print(result) # [1, 3, 5, 7, 9]
Читайте также:
Сравнение списков
Python поддерживает сравнение списков. Два списка считаются равными, если они содержат одинаковые элементы. Функция возвращает булево значение — True или False:
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # TrueПолучили, что списки равны.
В некоторых языках равенство ещё проверяется и по тому, ссылаются ли переменные на один и тот же объект. Обычно это делается через оператор ===. В Python это можно сделать через оператор is, который проверяет, имеют ли две переменные один и тот же адрес в памяти:
a = [1, 2, 3]
b = a
print(a is b) # TrueПолучили, что две переменные ссылаются на один и тот же адрес в памяти.
Встроенные функции для списков Python
В Python есть четыре функции, которые позволяют узнавать длину списка, сортировать его и возвращать максимальное и минимальное значение.
len()
Возвращает длину списка:
a = [5, 3, 1]
print(len(a)) # 3sorted()
Возвращает отсортированный список:
a = [8, 1, 3, 2]
print (sorted(a)) # [1, 2, 3, 8]min() и max()
Возвращают наименьший и наибольший элемент списка:
a = [1, 9, -2, 3]
print(min(a)) # -2
print(max(a)) # 9
Читайте также:
Методы списков Python
Чтобы проще управлять элементами списка, в стандартной библиотеке Python есть набор популярных методов для списков. Разберём основные из них.
append()
Добавляет новый элемент в конец списка:
a = [1, 2, 3]
a.append(4)
print(a) # [1, 2, 3, 4]extend()
Добавляет набор элементов в конец списка:
a = [1, 2, 3]
a.extend([4, 5])
print(a) # [1, 2, 3, 4, 5]Внутрь метода extend() нужно передать итерируемый объект — например, другой list или строку.
Вот так метод extend() добавит строку:
a = ['cat', 'dog', 'bat']
a.extend('mouse')
print(a) # ['cat', 'dog', 'bat', 'm', 'o', 'u', 's', 'e']Заметьте, что строка добавилась посимвольно.
insert()
Добавляет новый элемент по индексу:
a = [1, 2, 3]
a.insert(0, 4)
print(a) # [4, 1, 2, 3]Сначала мы передаём индекс, по которому хотим вставить новый элемент, а затем сам элемент.
remove()
Удаляет элемент из списка:
a = [1, 2, 3, 1]
a.remove(1)
print(a) # [2, 3, 1]Метод удаляет только первое вхождение элемента. Остальные остаются нетронутыми.
Если элемента нет в списке, Python вернёт ошибку и программа прервётся:
a = [1, 2, 3, 1]
a.remove(5) # ValueError: list.remove(x): x not in listОшибка говорит, что элемента нет в списке.
Читайте также:
clear()
Удаляет все элементы из списка и делает его пустым:
a = [1, 2, 3]
a.clear()
print(a) # []index()
Возвращает индекс элемента списка в Python:
a = [1, 2, 3]
print(a.index(2)) # 1Если элемента нет в списке, выведется ошибка:
a = [1, 2, 3]
print(a.index(4)) # ValueError: 4 is not in listpop()
Удаляет элемент по индексу и возвращает его как результат:
a = [1, 2, 3]
print(a.pop()) # 3
print(a) # [1, 2]Мы не передали индекс в метод, поэтому он удалил последний элемент списка. Если передать индекс, то получится так:
a = [1, 2, 3]
print(a.pop(1)) # 2
print(a) # [1, 3]count()
Считает, сколько раз элемент повторяется в списке:
a = [1, 1, 1, 2]
print(a.count(1)) # 3sort()
Сортирует список:
a = [4, 1, 5, 2]
a.sort()
print(a) # [1, 2, 4, 5]Если нам нужно отсортировать в обратном порядке — от большего к меньшему, — в методе есть дополнительный параметр reverse:
a = [4, 1, 5, 2]
a.sort(reverse=True)
print(a) # [5, 4, 2, 1]reverse()
Переставляет элементы в обратном порядке:
a = [1, 3, 2, 4]
a.reverse()
print(a) # [4, 2, 3, 1]copy()
Копирует список:
a = [1, 2, 3]
b = a.copy()
print(b) # [1, 2, 3]Для того чтобы быстро находить нужные методы во время работы, пользуйтесь этой шпаргалкой:
| Метод | Что делает |
|---|---|
| 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.
Больше интересного про код — в нашем телеграм-канале. Подписывайтесь!
Python для всех
Вы освоите Python на практике и создадите проекты для портфолио — телеграм-бот, веб-парсер и сайт с нуля. А ещё получите готовый план выхода на удалёнку и фриланс. Спикер — руководитель отдела разработки в «Сбере».
Пройти бесплатно