8.1. Создание списка
Начнем с примера. Предположим, что нам необходимо обработать информацию о курсах валют:
Мы можем курс валюты на каждый день поместить в отдельную переменную:
Схематично:
А, если обработать необходимо курсы валют за последние два года…? Тут нам на помощь приходят списки. Их можно рассматривать как аналог массива в других языках программирования, за исключением важной особенности – списки в качестве своих элементов могут содержать любые объекты. Но обо всем по порядку.
Список (list) в Python является объектом30, поэтому может быть присвоен переменной (переменная, как и в предыдущих случая, хранит адрес объекта класса список).
Представим список для нашей задачи с курсом валют:
Список позволяет хранить разнородные данные, обращаться к которым можно через имя списка (в данном случае переменную e).
Рассмотрим, как Python работает со списками в памяти:
Видим, что переменная e содержит адрес списка (id6). Каждый элемент списка является указателем (хранит адрес) другого объекта (в данном случае вещественных чисел).
В общем виде создание списка выглядит следующим образом:
Отмечу, что на месте элементов списка могут находиться выражения, а не просто отдельные объекты.
8.2. Операции над списками
Обращаться к отдельным элементам списка можно по их индексу (позиции), начиная с нуля:
Обращение по несуществующему индексу вызовет ошибку:
До настоящего момента мы рассматривали типы данных (классы), которые нельзя было изменить. Вспомните, как Python ругался при попытке изменить строку. Списки можно изменить. Проведем эксперимент:
В примере мы создали список и изменили элемент, находящийся в позиции 1. Видим, что список изменился. Рассмотрим еще один пример и покажем, что происходит в памяти:
В памяти:
Производим изменения списка:
В момент изменения списка в памяти создается новый строковый объект ‘hello’. Затем адрес на этот объект (id7) помещается в первую ячейку списка (вместо id2). Python увидит, что на объект по адресу id2 нет ссылок, поэтому удалит его из памяти.
Список (list), наверное, наиболее часто встречающийся тип данных, с которым приходится сталкиваться при написании программ. Это связано со встроенными в Python функциями, которые позволяют легко и быстро обрабатывать списки:
len(L) – возвращает число элементов в списке L
max(L) – возвращает максимальное значение в списке L
min(L) – возвращает минимальное значение в списке L
sum(L) – возвращает сумму значений в списке L
sorted(L) – возвращает копию списка L, в котором элементы упорядочены
по возрастанию. Не изменяет список L
Примеры вызовов функций:
8.3. Псевдонимы и копирование списков
Рассмотрим важную особенность списков. Выполним следующий код:
В Python две переменные называются псевдонимами32, когда они содержат одинаковые адреса памяти.
На схеме видно, что переменные p и h указывают на один и тот же список:
Создание псевдонимов – особенность списков, т.к. они могут изменяться. Будьте крайне внимательны.
Возникает вопрос, как проверить, ссылаются ли переменные на один и тот же список:
К спискам применимы два вида копирования. Первый вид – поверхностное копирование, при котором создается новый объект, но он будет заполнен ссылками на элементы, которые содержались в оригинале:
Следующий рисунок демонстрирует схему размещения ссылок на объекты при поверхностном копировании:
Второй вид копирования – глубокое копирование. При глубоком копировании создается новый объект и рекурсивно создаются копии всех объектов, содержащихся в оригинале:
C одной стороны список предоставляет возможность модификации, с другой – появляется опасность незаметно изменить список за счет создания псевдонимов или при поверхностном копировании.
8.4. Методы списка
Вспомните, что мы говорили о строковых методах. Для списков ситуация будет аналогичная. Далее приведены наиболее популярные методы списка:
Еще несколько полезных методов для списка:
Методов много, поэтому для их запоминания рекомендую выполнить каждый из перечисленных выше методов для различных аргументов и посмотреть, что они возвращают. Это обязательно пригодится при написании программ.
8.5. Преобразование типов
Очень часто появляется потребность в изменении строк, но напрямую мы этого сделать не можем. Тогда нам на помощь приходят списки. Преобразуем строку в список, изменим список, затем вернем его в строку:
Отдельно рассмотрим несколько примеров строкового метода join:
Метод join принимает на вход список, который необходимо преобразовать в строку, а в качестве строкового объекта указывается соединитель элементов списка.
Аналогично можно преобразовать число к списку (через строку) и затем изменить полученный список:
Если строка содержит разделитель, то ее можно преобразовать к списку с помощью строкового метода split, который по умолчанию в качестве разделителя использует пробел:
Возьмем другой разделитель:
8.6. Вложенные списки
Мы уже упоминали, что в качестве элементов списка могут быть объекты любого типа, например, списки:
Подобные структуры используются для хранения матриц.
Обращение (изменение) к вложенному списку происходит через указание двух индексов:
Схематично вложенные списки выглядят следующим образом: