ГЛАВА 8. СПИСКИ В PYTHON

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. Вложенные списки

Мы уже упоминали, что в качестве элементов списка могут быть объекты любого типа, например, списки:

Подобные структуры используются для хранения матриц.

Обращение (изменение) к вложенному списку происходит через указание двух индексов:

Схематично вложенные списки выглядят следующим образом: