Что такое списки в Python
Список — это упорядоченный набор значений в квадратных скобках через запятую. Его создают один раз, кладут в переменную и дальше работают со всем набором сразу, а не с десятком отдельных переменных.
marks = [5, 4, 5, 3, 5]
friends = ["Аня", "Миша", "Оля"]
empty = []
mixed = [7, "кот", True, 2.5]
print(marks)
print(len(friends))
[5, 4, 5, 3, 5]
3
Список marks содержит 5 оценок, friends — 3 имени, empty пока пуст, а mixed показывает, что в одном списке могут лежать значения разных типов. На практике так делают редко: удобнее, когда все элементы одного вида, — тогда их легко складывать, сравнивать и сортировать. Тип списка в Python называется list, и пустой список можно создать как [] или list().
Зачем вообще нужны списки в Python? Представьте программу, которая хранит оценки 25 учеников. Без списка понадобится 25 переменных и 25 одинаковых строк кода для подсчёта среднего. Со списком хватит одной переменной и короткого цикла. В школьной информатике эту структуру называют одномерным массивом: по федеральной образовательной программе массивы изучают в 9 классе[1], и в Python их роль выполняют именно списки.
Индексы: счёт с нуля и с конца
Индекс — это номер элемента в списке, и счёт в Python начинается с 0: первый элемент имеет индекс 0, второй — 1. Отрицательные индексы считают с конца: -1 — последний элемент, -2 — предпоследний.
planets = ["Меркурий", "Венера", "Земля", "Марс"]
print(planets[0])
print(planets[2])
print(planets[-1])
planets[3] = "Красная планета"
print(planets)
| Элемент | Меркурий | Венера | Земля | Марс |
| Индекс слева | 0 | 1 | 2 | 3 |
| Индекс справа | -4 | -3 | -2 | -1 |
Почему индексы списков в Python начинаются с нуля? Индекс показывает, на сколько шагов нужно отойти от начала: до первого элемента — 0 шагов. Так устроено большинство языков программирования, и к этому быстро привыкают. Последний индекс всегда на единицу меньше длины: в списке из 4 элементов это 3. Обращение к planets[4] вызовет ошибку IndexError — её разбор есть на странице об ошибке IndexError.
Через индекс элемент можно не только прочитать, но и заменить: planets[3] = "Красная планета" кладёт новое значение на место старого. Длина списка при этом не меняется.
Методы append, insert, remove и pop
Чтобы изменить состав списка, используют 4 главных метода: append добавляет в конец, insert — в нужное место, remove удаляет по значению, pop — по индексу. Методы вызываются через точку после имени списка.
| Метод | Что делает | Пример | Список после |
append(x) | Добавляет x в конец | a.append(9) | [1, 2, 3, 9] |
insert(i, x) | Вставляет x на место i | a.insert(0, 7) | [7, 1, 2, 3] |
remove(x) | Удаляет первое найденное x | a.remove(2) | [1, 3] |
pop() | Удаляет и возвращает последний | a.pop() | [1, 2] |
pop(i) | Удаляет и возвращает элемент i | a.pop(0) | [2, 3] |
В таблице каждый пример выполняется для исходного списка a = [1, 2, 3]. Чаще всех нужен append: с его помощью список собирают по одному элементу, например из ввода пользователя.
backpack = []
backpack.append("тетрадь")
backpack.append("пенал")
backpack.insert(0, "учебник")
print(backpack)
taken = backpack.pop()
print("Достали:", taken)
backpack.remove("учебник")
print(backpack)
Важная деталь: метод remove удаляет только первое совпадение, а если значения нет совсем — выдаёт ошибку ValueError. Поэтому перед удалением полезно проверить if "учебник" in backpack:. Оператор in отвечает True или False на вопрос «есть ли такой элемент в списке». Методы append, insert, remove и pop меняют сам список и ничего нового не создают, поэтому писать backpack = backpack.append(...) нельзя: в переменной окажется None.
Длина и срезы списка
Функция len() возвращает количество элементов, а срез a[start:stop] — это новый список из части элементов: с индекса start до stop, не включая stop. Правило «правая граница не входит» здесь такое же, как у range.
week = ["пн", "вт", "ср", "чт", "пт", "сб", "вс"]
print(len(week))
print(week[0:5])
print(week[5:])
print(week[:3])
print(week[::2])
print(week[::-1])
7
['пн', 'вт', 'ср', 'чт', 'пт']
['сб', 'вс']
['пн', 'вт', 'ср']
['пн', 'ср', 'пт', 'вс']
['вс', 'сб', 'пт', 'чт', 'ср', 'вт', 'пн']
Если опустить начало среза, Python возьмёт элементы с самого первого, если опустить конец — до последнего включительно. Третье число — шаг: [::2] выбирает каждый второй элемент, а [::-1] переворачивает список. Срез никогда не вызывает IndexError: если границы выходят за пределы, он просто вернёт то, что есть, или пустой список. Это удобно, но иногда скрывает ошибку в расчёте индексов.
Перебор списка циклом for
Перебрать список — значит по очереди обработать каждый элемент, и для этого есть 2 способа: по значениям и по индексам. Первый короче, второй нужен, когда важен номер элемента или его надо заменить.
prices = [120, 45, 300, 80]
for p in prices:
print("Цена:", p)
for i in range(len(prices)):
prices[i] = prices[i] * 2
print(prices)
В первом цикле переменная p получает сами значения, и изменить список через неё не выйдет: p = p * 2 поменяет только копию числа. Во втором цикле i пробегает индексы 0, 1, 2, 3, и запись prices[i] = ... меняет элементы на месте. Если нужны и номер, и значение, используйте enumerate(prices). Подробно о переборе последовательностей рассказано в уроке про цикл for.
Функции sum, min, max и sorted
Для числовых списков в Python есть 4 готовые функции: sum складывает элементы, min и max находят наименьший и наибольший, sorted возвращает новый отсортированный список. Они избавляют от ручных циклов в простых случаях.
scores = [7, 3, 9, 4]
print(sum(scores), min(scores), max(scores))
print(sorted(scores))
print(sorted(scores, reverse=True))
print(scores)
scores.sort()
print(scores)
Обратите внимание на разницу: sorted(scores) создаёт новый список и не трогает старый, а метод scores.sort() сортирует сам список и возвращает None. Строки сортируются по алфавиту, точнее по кодам символов, поэтому заглавные буквы окажутся раньше строчных. Среднее значение считают как sum(scores) / len(scores) — только если список не пустой, иначе будет деление на ноль. Все эти функции описаны в официальной документации Python[2], там же перечислены остальные методы списков.
Одна коробка, два имени
Если написать b = a, нового списка не появится — это 2 имени для одного и того же набора, и изменение через b будет видно через a. Чтобы получить независимую копию, нужен срез a[:] или метод a.copy().
a = [1, 2, 3]
b = a
b.append(4)
print(a)
c = a[:]
c.append(5)
print(a)
print(c)
[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
Списки в Python изменяемые, а строки и числа — нет. Так это описано и в документации Python, в разделе о структурах данных. Поэтому с числами такой эффект не встречается: y = x; y = y + 1 не меняет x. Со списками же новички часто удивляются, что «испортился» исходный набор. Правило простое: присваивание не копирует, копию нужно сделать явно. Чем строки отличаются по поведению, разобрано в уроке про строки в Python.
Задачи на списки Python с автопроверкой
Чтобы закрепить приёмы, решите 6 задач в тренажёре вверху страницы: напишите код, нажмите «✓ Проверить», и решение запустится на нескольких тестах. Не прошедший тест покажет «Ожидалось» и «Получилось».
Во всех задачах числа или слова вводятся в одной строке через пробел, а input().split() превращает такую строку в набор слов. Для чисел добавьте list(map(int, ...)). Сначала попробуйте сами, затем откройте «Подсказку», а «Показать решение» оставьте на крайний случай. Самопроверка закрепляет материал лучше перечитывания — это подтвердило исследование Roediger и Karpicke[3], поэтому через пару дней вернитесь к задачам снова. Ещё 8 упражнений с разбором собраны на странице задач на списки.
Когда список не подходит
Список не подходит, когда данные нужно искать не по номеру, а по названию, или когда важна уникальность. В этих 4 случаях лучше другая структура.
- Телефонная книга на 100 контактов. Искать номер по имени удобнее в словаре: там доступ по ключу, а не перебор.
- Набор из 1000 уникальных слов. Множество
setсамо убирает повторы и быстрее отвечает на вопрос «есть ли слово». - Координаты точки из 2 чисел, которые не меняются. Подойдёт кортеж — неизменяемая пара
(x, y). - Таблица на 10 000 строк с вычислениями. Для больших таблиц в профессиональной работе используют специальные библиотеки, а на школьном уровне хватит вложенных наборов.
«Индексы в Python начинаются с единицы, как в тетради». Это миф: первый элемент имеет индекс 0, и об этом прямо сказано в учебнике Python.
«
b = aсоздаёт копию». Это не подтверждается запуском кода: обе переменные указывают на один объект, и изменение видно через оба имени.
Чего делать нельзя
Нельзя обращаться к элементу по индексу, равному длине: в наборе из 5 элементов последний индекс — 4. Остальные правила защищают от тихих ошибок.
- Нельзя присваивать результат append обратно:
a = a.append(1)превращает переменную в None. - Не следует удалять элементы во время перебора того же набора циклом for — часть элементов будет пропущена.
- Не стоит называть переменную
list: это имя встроенного типа, и после такой заменыlist()перестанет работать. - Не допускается считать среднее пустого набора без проверки длины — будет ZeroDivisionError.
- Нельзя путать
sort()иsorted(): первый возвращает None, второй — новый отсортированный набор. - Не стоит хранить в одном наборе числа и строки вперемешку, если их потом нужно сортировать: Python 3 не сравнивает число со строкой.
Правила именования переменных и оформления кода описаны в руководстве PEP 8[4]: имена в стиле snake_case, отступ 4 пробела. Python Software Foundation публикует это руководство вместе с документацией, а короткий пересказ — на странице про стиль кода Python.
Источники
[1] Приказ Минпросвещения России от 18.05.2023 № 370 «Об утверждении федеральной образовательной программы основного общего образования».
[2] The Python Tutorial (официальная документация Python 3). Python Software Foundation.
[3] Roediger H. L., Karpicke J. D. Test-enhanced learning: Taking memory tests improves long-term retention // Psychological Science. 2006. Vol. 17, № 3. P. 249–255.
[4] van Rossum G., Warsaw B., Coghlan N. PEP 8 — Style Guide for Python Code. Python Software Foundation, 2001.
Вопросы и ответы
Чем список отличается от массива?
В школьной информатике массивом называют набор однотипных элементов с номерами. В Python его роль играет list: он умеет то же самое и вдобавок может менять длину на ходу.
Как проверить, что набор пустой?
Сравните длину с нулём: if len(a) == 0:. Короче работает if not a: — пустой набор считается ложным значением.
Как превратить строку из ввода в числа?
Запись list(map(int, input().split())) делит строку по пробелам и превращает каждую часть в целое число. Если в строке есть буквы, будет ValueError.
Можно ли положить один набор внутрь другого?
Да, получится вложенная структура, например таблица: t = [[1, 2], [3, 4]]. К элементу обращаются двумя индексами: t[1][0] равно 3.
Как узнать, на каком месте стоит элемент?
Метод index(x) вернёт индекс первого совпадения. Если элемента нет, будет ошибка, поэтому сначала проверяйте x in a.
Почему print выводит элементы в квадратных скобках?
Так Python показывает весь набор целиком. Чтобы вывести элементы через пробел без скобок и кавычек, используйте ' '.join(...) для строк или цикл с print(x, end=' ').