Списки в Python

В этой статье мы подробно рассмотрим списки (list) в Python — один из самых гибких и часто используемых типов данных. Списки позволяют хранить коллекции элементов и манипулировать ими различными способами.

Что такое список?

Список в Python — это упорядоченная, изменяемая коллекция элементов, которые могут быть разных типов. Вы можете представить список как контейнер, в котором хранятся различные объекты, расположенные в определенном порядке.

Основные свойства списков:

  • Упорядоченность: элементы хранятся в том порядке, в котором они были добавлены
  • Изменяемость: можно добавлять, удалять и изменять элементы после создания списка
  • Индексируемость: к каждому элементу можно обратиться по его позиции (индексу)
  • Допускают дубликаты: один и тот же элемент может встречаться в списке несколько раз

Создание списков

Существует несколько способов создания списков в Python:

С помощью квадратных скобок []

Python 3.13
# Пустой список
>>> empty_list = []
>>> print(empty_list)
[]
# Список чисел >>> numbers = [1, 2, 3, 4, 5] >>> print(numbers)
[1, 2, 3, 4, 5]
# Список строк >>> fruits = ["яблоко", "банан", "вишня"] >>> print(fruits)
['яблоко', 'банан', 'вишня']
# Список разных типов данных >>> mixed = [1, "привет", True, 3.14] >>> print(mixed)
[1, 'привет', True, 3.14]
# Вложенные списки (список списков) >>> matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] >>> print(matrix)
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

С помощью конструктора list()

Python 3.13
# Создание пустого списка
>>> empty_list = list()
>>> print(empty_list)
[]
# Создание списка из строки (каждый символ становится элементом) >>> chars = list("Python") >>> print(chars)
['P', 'y', 't', 'h', 'o', 'n']
# Создание списка из других итерируемых объектов >>> tuple_to_list = list((1, 2, 3)) >>> print(tuple_to_list)
[1, 2, 3]
>>> set_to_list = list({1, 2, 3}) >>> print(set_to_list)
[1, 2, 3]

С помощью генераторов списков

Python 3.13
# Создание списка квадратов чисел от 0 до 9
>>> squares = [x**2 for x in range(10)]
>>> print(squares)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# Создание списка четных чисел от 0 до 9 >>> even_numbers = [x for x in range(10) if x % 2 == 0] >>> print(even_numbers)
[0, 2, 4, 6, 8]
# Генератор вложенных списков (матрица 3x3) >>> matrix = [[i + j for j in range(3)] for i in range(0, 9, 3)] >>> print(matrix)
[[0, 1, 2], [3, 4, 5], [6, 7, 8]]

Доступ к элементам списка

Индексация

В Python индексация начинается с 0, то есть первый элемент имеет индекс 0, второй — 1, и так далее:

Python 3.13
>>> fruits = ["яблоко", "банан", "вишня", "груша", "апельсин"]

# Получение элементов по индексу
>>> first_fruit = fruits[0]
>>> print(f"Первый фрукт: {first_fruit}")
Первый фрукт: яблоко
>>> second_fruit = fruits[1] >>> print(f"Второй фрукт: {second_fruit}")
Второй фрукт: банан
# Отрицательные индексы для доступа с конца списка >>> last_fruit = fruits[-1] >>> print(f"Последний фрукт: {last_fruit}")
Последний фрукт: апельсин
>>> second_last = fruits[-2] >>> print(f"Предпоследний фрукт: {second_last}")
Предпоследний фрукт: груша

Срезы (slices)

Срезы позволяют получить подсписок, указав начальный и конечный индексы:

Python 3.13
>>> fruits = ["яблоко", "банан", "вишня", "груша", "апельсин"]

# Синтаксис среза: список[начало:конец:шаг]
# Начало включается, конец не включается!

# Первые три элемента
>>> first_three = fruits[0:3]
>>> print(f"Первые три фрукта: {first_three}")
Первые три фрукта: ['яблоко', 'банан', 'вишня']
# То же самое, но начальный индекс можно опустить, если он 0 >>> first_three = fruits[:3] >>> print(f"Первые три фрукта: {first_three}")
Первые три фрукта: ['яблоко', 'банан', 'вишня']
# От второго до четвертого >>> middle = fruits[1:4] >>> print(f"Фрукты с индексами 1-3: {middle}")
Фрукты с индексами 1-3: ['банан', 'вишня', 'груша']
# От третьего до конца >>> to_end = fruits[2:] >>> print(f"Фрукты с третьего до конца: {to_end}")
Фрукты с третьего до конца: ['вишня', 'груша', 'апельсин']
# Каждый второй элемент >>> every_second = fruits[::2] >>> print(f"Каждый второй фрукт: {every_second}")
Каждый второй фрукт: ['яблоко', 'вишня', 'апельсин']
# Разворот списка >>> reversed_list = fruits[::-1] >>> print(f"Список в обратном порядке: {reversed_list}")
Список в обратном порядке: ['апельсин', 'груша', 'вишня', 'банан', 'яблоко']

Изменение элементов списка

В отличие от строк, списки являются изменяемыми, то есть вы можете изменять, добавлять и удалять элементы:

Python 3.13
>>> fruits = ["яблоко", "банан", "вишня"]

# Изменение элемента
>>> fruits[0] = "киви"
>>> print(fruits)
['киви', 'банан', 'вишня']
# Изменение нескольких элементов с помощью среза >>> numbers = [1, 2, 3, 4, 5] >>> numbers[1:4] = [20, 30, 40] >>> print(numbers)
[1, 20, 30, 40, 5]
# Можно даже заменить несколько элементов на другое количество >>> numbers = [1, 2, 3, 4, 5] >>> numbers[1:4] = [20, 30] >>> print(numbers)
[1, 20, 30, 5]

Основные методы списков

Python предоставляет множество встроенных методов для работы со списками:

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

Python 3.13
>>> fruits = ["яблоко", "банан"]

# Добавление элемента в конец списка
>>> fruits.append("вишня")
>>> print(fruits)
['яблоко', 'банан', 'вишня']
# Вставка элемента на определенную позицию >>> fruits.insert(1, "апельсин") >>> print(fruits)
['яблоко', 'апельсин', 'банан', 'вишня']
# Добавление элементов из другого списка >>> more_fruits = ["груша", "виноград"] >>> fruits.extend(more_fruits) >>> print(fruits)
['яблоко', 'апельсин', 'банан', 'вишня', 'груша', 'виноград']
# Объединение списков с помощью оператора + >>> combined = fruits + ["ананас", "манго"] >>> print(combined)
['яблоко', 'апельсин', 'банан', 'вишня', 'груша', 'виноград', 'ананас', 'манго']

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

Python 3.13
>>> fruits = ["яблоко", "банан", "вишня", "апельсин", "банан"]

# Удаление элемента по значению (удаляет только первое вхождение)
>>> fruits.remove("банан")
>>> print(fruits)
['яблоко', 'вишня', 'апельсин', 'банан']
# Удаление элемента по индексу и возврат его значения >>> removed = fruits.pop(1) >>> print(f"Удален: {removed}")
Удален: вишня
>>> print(f"Список после удаления: {fruits}")
Список после удаления: ['яблоко', 'апельсин', 'банан']
# Если индекс не указан, pop() удаляет и возвращает последний элемент >>> last = fruits.pop() >>> print(f"Последний элемент: {last}")
Последний элемент: банан
>>> print(fruits)
['яблоко', 'апельсин']
# Удаление всех элементов из списка >>> fruits.clear() >>> print(f"Пустой список: {fruits}")
Пустой список: []
# Оператор del для удаления элементов по индексу или срезу >>> numbers = [1, 2, 3, 4, 5] >>> del numbers[0] >>> print(numbers)
[2, 3, 4, 5]
>>> del numbers[1:3] >>> print(numbers)
[2, 5]

Поиск и подсчет элементов

Python 3.13
>>> fruits = ["яблоко", "банан", "вишня", "банан", "груша"]

# Проверка наличия элемента в списке
>>> print("банан" in fruits)
True
>>> print("арбуз" in fruits)
False
# Поиск индекса первого вхождения элемента >>> banana_index = fruits.index("банан") >>> print(f"Индекс первого банана: {banana_index}")
Индекс первого банана: 1
# Подсчет количества вхождений элемента >>> banana_count = fruits.count("банан") >>> print(f"Количество бананов: {banana_count}")
Количество бананов: 2

Сортировка и разворот

Python 3.13
# Сортировка списка (изменяет исходный список)
>>> numbers = [3, 1, 4, 1, 5, 9, 2]
>>> numbers.sort()
>>> print(f"Отсортированный список: {numbers}")
Отсортированный список: [1, 1, 2, 3, 4, 5, 9]
# Сортировка в обратном порядке >>> numbers.sort(reverse=True) >>> print(f"Обратная сортировка: {numbers}")
Обратная сортировка: [9, 5, 4, 3, 2, 1, 1]
# Для строк сортировка идет по алфавиту >>> fruits = ["банан", "яблоко", "вишня", "груша"] >>> fruits.sort() >>> print(f"Фрукты по алфавиту: {fruits}")
Фрукты по алфавиту: ['банан', 'вишня', 'груша', 'яблоко']
# Разворот списка (изменяет исходный список) >>> fruits.reverse() >>> print(f"Фрукты в обратном порядке: {fruits}")
Фрукты в обратном порядке: ['яблоко', 'груша', 'вишня', 'банан']
# Если не хотите изменять исходный список, используйте sorted() >>> original = [3, 1, 4, 1, 5] >>> sorted_list = sorted(original) >>> print(f"Оригинал: {original}")
Оригинал: [3, 1, 4, 1, 5]
>>> print(f"Отсортированная копия: {sorted_list}")
Отсортированная копия: [1, 1, 3, 4, 5]

Копирование списков

При работе со списками важно понимать, как работает присваивание и копирование:

Python 3.13
# Создаем список
>>> original = [1, 2, 3]

# Присваивание не создает копию — обе переменные указывают на один список
>>> reference = original
>>> reference.append(4)
>>> print(f"Оригинал после изменения ссылки: {original}")
Оригинал после изменения ссылки: [1, 2, 3, 4]
# Правильные способы копирования списка: # 1. Метод copy() >>> copy1 = original.copy() # 2. Использование среза [:] >>> copy2 = original[:] # 3. Функция list() >>> copy3 = list(original) # Проверим, что копии не связаны с оригиналом >>> copy1.append(5) >>> print(f"Оригинал: {original}")
Оригинал: [1, 2, 3, 4]
>>> print(f"Копия 1: {copy1}")
Копия 1: [1, 2, 3, 4, 5]
# Но осторожно с вложенными списками - это будет "неглубокая" копия >>> nested = [[1, 2], [3, 4]] >>> shallow_copy = nested.copy() >>> shallow_copy[0][0] = 99 >>> print(f"Оригинал вложенного списка: {nested}")
Оригинал вложенного списка: [[99, 2], [3, 4]]
# Для "глубокой" копии используйте модуль copy >>> import copy >>> deep_copy = copy.deepcopy(nested) >>> deep_copy[0][0] = 100 >>> print(f"Вложенный оригинал: {nested}")
Вложенный оригинал: [[99, 2], [3, 4]]
>>> print(f"Глубокая копия: {deep_copy}")
Глубокая копия: [[100, 2], [3, 4]]

Практический пример использования списка

Python 3.13
# Список студентов и их оценок
>>> students = ["Анна", "Иван", "Мария", "Петр", "Елена"]
>>> grades = [95, 82, 90, 78, 88]

# Нахождение студента с наивысшим баллом
>>> highest_score = max(grades)
>>> top_student_index = grades.index(highest_score)
>>> print(f"Лучший студент: {students[top_student_index]} с оценкой {highest_score}")
Лучший студент: Анна с оценкой 95
# Расчет средней оценки >>> average_grade = sum(grades) / len(grades) >>> print(f"Средняя оценка: {average_grade:.2f}")
Средняя оценка: 86.60

Распространенные ошибки при работе со списками

1. Изменение списка во время итерации

Python 3.13
# Неправильно:
>>> numbers = [1, 2, 3, 4, 5]
>>> try:
...     for number in numbers:
...         if number % 2 == 0:
...             # Опасно! Изменяет список во время итерации
...             numbers.remove(number)
...     print(numbers)
... except Exception as e:
...     print(f"Этот код может вызвать неожиданное поведение")
Этот код может вызвать неожиданное поведение
# Правильно: >>> numbers = [1, 2, 3, 4, 5] >>> odd_numbers = [] >>> for num in numbers: ... if num % 2 != 0: ... odd_numbers.append(num) ... numbers = odd_numbers ... print(f"Только нечетные числа: {numbers}")
Только нечетные числа: [1, 3, 5]

2. Неглубокое копирование вложенных списков

Python 3.13
# Проблема:
>>> original = [[1, 2], [3, 4]]
>>> shallow = original.copy()
>>> shallow[0][0] = 99
>>> print(f"Оригинал изменился: {original}")
Оригинал изменился: [[99, 2], [3, 4]]
# Решение: >>> import copy >>> original = [[1, 2], [3, 4]] >>> deep = copy.deepcopy(original) >>> deep[0][0] = 999 >>> print(f"Оригинал: {original}")
Оригинал: [[1, 2], [3, 4]]
>>> print(f"Глубокая копия: {deep}")
Глубокая копия: [[999, 2], [3, 4]]

3. Выход за границы списка

Python 3.13
# Ошибка:
>>> numbers = [1, 2, 3]
>>> try:
...     value = numbers[3]  # IndexError: list index out of range
... except IndexError as e:
...     print(f"Ошибка: {e}")
Ошибка: list index out of range
# Безопасный подход: >>> index = 3 >>> if index < len(numbers): ... value = numbers[index] ... else: ... value = None ... print(f"Значение: {value}")
Значение: None

Проверка понимания

Какой из следующих способов правильно создаст копию списка, не связанную с оригиналом?


Мы с вами на связи
Русский