Урок курса

Список: изменение и перебор

Python для новичков

В прошлом уроке список уже был создан, и мы научились обращаться к его элементам по индексу и срезам. Теперь переходим к изменению: начнём с добавления новых элементов.

Добавление элементов: append и insert

Список в Python — изменяемая структура: элементы можно добавлять, удалять и переставлять прямо в том же объекте, без создания нового. Два основных метода для добавления — append() и insert().

append() — самый простой случай: добавляет один элемент в конец.

tasks = ["купить хлеб", "позвонить врачу"]
tasks.append("сделать зарядку")
print(tasks)
# ['купить хлеб', 'позвонить врачу', 'сделать зарядку']

Длина списка после вызова увеличивается на 1. Метод изменяет список на месте и возвращает None — это значит, что писать tasks = tasks.append(...) бессмысленно: переменная станет None.

insert() нужен, когда элемент надо поместить не в конец, а в конкретную позицию. Синтаксис: lst.insert(i, element), где i — индекс, на котором окажется новый элемент.

tasks = ["купить хлеб", "позвонить врачу", "сделать зарядку"]
tasks.insert(1, "выпить кофе")
print(tasks)
# ['купить хлеб', 'выпить кофе', 'позвонить врачу', 'сделать зарядку']

Все элементы начиная с позиции 1 сдвигаются вправо, освобождая место. Элемент с индексом 1 до вставки ("позвонить врачу") теперь стоит под индексом 2.

Если передать индекс, равный длине списка или больший, Python просто добавит элемент в конец — ошибки не будет. Отрицательные индексы тоже работают, но поведение может быть неочевидным, поэтому для добавления в конец проще использовать append().

Главное отличие между двумя методами:

  • append() — всегда в конец, один аргумент.
  • insert() — в указанную позицию, два аргумента: индекс и значение.

Оба метода изменяют исходный список и не возвращают ничего полезного.

Удаление элементов: remove и pop

Удалять элементы из списка можно двумя способами: по значению и по индексу. Под каждый случай — свой метод.

remove() ищет в списке первое вхождение указанного значения и удаляет его.

tasks = ["купить хлеб", "выпить кофе", "позвонить врачу", "выпить кофе"]
tasks.remove("выпить кофе")
print(tasks)
# ['купить хлеб', 'позвонить врачу', 'выпить кофе']

Обратите внимание: удалился только первый «выпить кофе», второй остался. Метод не трогает дубликаты дальше первого совпадения.

Если передать значение, которого в списке нет, Python выбросит ValueError:

tasks = ["купить хлеб", "позвонить врачу"]
tasks.remove("сходить в спортзал")  # ValueError: list.remove(x): x not in list

Чтобы не словить ошибку, перед удалением проверяйте наличие через in:

task_to_remove = "сходить в спортзал"
if task_to_remove in tasks:
    tasks.remove(task_to_remove)
else:
    print("Такой задачи нет в списке")

pop() работает иначе: удаляет элемент по индексу и при этом возвращает его. Это принципиальное отличие от remove() — вы получаете удалённое значение обратно.

tasks = ["купить хлеб", "позвонить врачу", "сделать зарядку"]
done = tasks.pop(1)
print(done)   # позвонить врачу
print(tasks)  # ['купить хлеб', 'сделать зарядку']

Без аргумента pop() удаляет последний элемент — это удобно, когда список используется как стек:

tasks = ["купить хлеб", "позвонить врачу", "сделать зарядку"]
last = tasks.pop()
print(last)   # сделать зарядку
print(tasks)  # ['купить хлеб', 'позвонить врачу']

Если передать индекс, которого не существует, получите IndexError — та же ошибка, что при обращении к несуществующему элементу через квадратные скобки:

tasks = ["купить хлеб"]
tasks.pop(5)  # IndexError: pop index out of range

Вот ключевые различия между двумя методами:

  • remove(value) — удаляет по значению, возвращает None, выбрасывает ValueError если значения нет.
  • pop(i) — удаляет по индексу, возвращает удалённый элемент, выбрасывает IndexError если индекс вне диапазона.

Выбор между ними зависит от задачи: если вы знаете, что именно хотите убрать — remove(), если знаете, где оно стоит или нужен сам удалённый элемент — pop().

Изменение элемента по индексу и перебор списка циклом for

Методы append, insert, remove и pop добавляют и удаляют элементы. Но иногда нужно не добавить новый элемент, а заменить уже существующий — исправить опечатку или обновить задачу. Для этого используется присваивание по индексу.

Синтаксис простой: lst[i] = new_value. Никакого метода — просто указываете индекс и записываете новое значение.

tasks = ["купить хлеб", "позванить врачу", "сделать зарядку"]
tasks[1] = "позвонить врачу"  # исправляем опечатку
print(tasks)
# ['купить хлеб', 'позвонить врачу', 'сделать зарядку']

Список изменился на месте: элемент под индексом 1 заменён, остальные не сдвинулись. Длина списка при этом не меняется — замена, а не вставка.

Важно: индекс должен существовать. Если список из трёх элементов, допустимые индексы — 0, 1, 2-1, -2, -3 для отрицательных). Попытка записать по несуществующему индексу даст IndexError:

tasks = ["купить хлеб", "позвонить врачу"]
tasks[5] = "новая задача"  # IndexError: list assignment index out of range

Это та же ошибка, что при чтении по несуществующему индексу — Python одинаково реагирует на выход за границы при чтении и при записи.


Теперь о переборе. До этого момента мы обращались к конкретным элементам через индекс. Но часто нужно пройтись по всему списку — вывести каждую задачу, проверить каждый элемент. Для этого используется цикл for.

tasks = ["купить хлеб", "позвонить врачу", "сделать зарядку"]
for task in tasks:
    print(task)
# купить хлеб
# позвонить врачу
# сделать зарядку

Конструкция for task in tasks: на каждой итерации берёт следующий элемент списка и присваивает его переменной task. Количество итераций равно длине списка — Python сам останавливается, когда элементы заканчиваются.

Здесь task — это просто имя переменной, можно назвать её как угодно. Главное, что на каждом шаге цикла она содержит текущий элемент, а не его индекс.

Это отличается от того, как вы использовали for раньше с range(): там переменная получала числа от 0 до n-1. Здесь переменная получает сами элементы — строки, числа или что угодно, что лежит в списке.

Если нужно и вывести элемент, и знать его порядковый номер, проще всего завести отдельный счётчик:

tasks = ["купить хлеб", "позвонить врачу", "сделать зарядку"]
n = 1
for task in tasks:
    print(f"{n}. {task}")
    n += 1
# 1. купить хлеб
# 2. позвонить врачу
# 3. сделать зарядку

Такой приём — ручной счётчик внутри цикла — работает с любым списком и не требует ничего нового.

Программа-список дел: объединение всех операций

Все методы, которые мы разобрали, редко используются по одному. В реальных программах они работают вместе: что-то добавили, что-то удалили, что-то исправили, в конце вывели результат. Посмотрим, как это выглядит в связке.

Предположим, вы ведёте список дел на день. Сначала формируете базовый список:

tasks = ["купить продукты", "оплатить интернет", "убраться дома"]

Потом вспоминаете, что с утра нужно сначала сделать зарядку — вставляете её в начало:

tasks.insert(0, "сделать зарядку")
# ['сделать зарядку', 'купить продукты', 'оплатить интернет', 'убраться дома']

Добавляете ещё одну задачу в конец, о которой вспомнили позже:

tasks.append("позвонить маме")
# ['сделать зарядку', 'купить продукты', 'оплатить интернет', 'убраться дома', 'позвонить маме']

Замечаете опечатку в третьей задаче — исправляете по индексу:

tasks[2] = "оплатить интернет и телефон"

Одну задачу выполнили — убираете её через pop(), заодно сохраняете название, чтобы вывести подтверждение:

done = tasks.pop(0)
print(f"Выполнено: {done}")
# Выполнено: сделать зарядку

Оказывается, «убраться дома» уже не нужно — отменяете через remove():

if "убраться дома" in tasks:
    tasks.remove("убраться дома")

Теперь выводим финальный список — перебираем циклом for:

print("\nСписок дел на сегодня:")
for task in tasks:
    print(f"- {task}")

Вывод:

Список дел на сегодня:
- купить продукты
- оплатить интернет и телефон
- позвонить маме

Вот полная программа целиком:

tasks = ["купить продукты", "оплатить интернет", "убраться дома"]

tasks.insert(0, "сделать зарядку")
tasks.append("позвонить маме")
tasks[2] = "оплатить интернет и телефон"

done = tasks.pop(0)
print(f"Выполнено: {done}")

if "убраться дома" in tasks:
    tasks.remove("убраться дома")

print("\nСписок дел на сегодня:")
for task in tasks:
    print(f"- {task}")

Эта программа показывает типичный жизненный цикл списка: инициализация → динамическое изменение по ходу выполнения → итоговый вывод. Такой паттерн встречается повсюду: список задач, корзина в магазине, очередь сообщений — везде один и тот же ритм работы. Освоив его здесь, вы сможете применять его к любым данным.

Попробуйте решить

Дан список:

tasks = ['купить молоко', 'позвонить врачу', 'сделать зарядку']
tasks.append('прочитать книгу')

Что теперь хранится в tasks[-1]?

Продолжить с проверкой и прогрессом

Откройте интерактивный раннер с заданиями урока.

Перейти к интерактивному уроку