
Знакомство со списками
Синтаксис. Модификация. Проверка существования значения
Штана Альберт Игоревич
Знакомство со списками
Программирование становится по-настоящему интересным, когда появляется возможность работать с наборами элементов. Вот лишь некоторые примеры того, где они встречаются:
- Подсчет общей суммы в заказе на основании каждой из позиций
- Обработка набора DOM-узлов (HTML, фронтенд-разработка)
- Постраничный вывод данных на сайте
- Вывод списка друзей, сообщений, фильмов и тому подобное
Любые списки, которые окружают нас в реальном или виртуальном мире, являются коллекциями элементов с точки зрения программирования. В Python для их хранения используется список – структура данных, позволяющая работать с набором как с единым целым:
# Определение списка покупок
shops = ['мыло', 'порошок', 'зубная паста']
В отличие от примитивных типов данных, списки в Python могут изменяться. Причем, как по содержимому, так и по размеру самого списка. Это сильно влияет на работу с ними и добавляет с одной стороны больше возможностей, а с другой – ответственности.
Используя списки, одну и ту же задачу можно решить множеством разных способов. Только некоторые из них будут хорошими, остальные же — неэффективными, сложными в отладке и анализе.
Именно поэтому спискам посвящено несколько статей и множество часов работы с ними.
Далее рассматриваются несколько ситуаций, которые традиционно решаются с помощью списков. Основные темы:
- Манипуляции со списками
- Обработка списков в циклах
- Работа с вложенными списками и вложенными циклами
- Сортировка списков
Синтаксис
Списки в Python представляют любые упорядоченные наборы, коллекции элементов, ученики в группе или друзья в вашей социальной сети. Задача списка — представить такие коллекции в виде единой структуры, которая позволяет работать с ними как с единым целым.
Определение списка
# Создание пустого списка
items = [] # Или так items = list()
# Создание списка с тремя элементами
animals = ['cats', 'dogs', 'birds']
В примере происходит определение списка ['cats', 'dogs', 'birds'], который затем присваивается переменной animals.
Обратите внимание на именование переменных, содержащих списки. Они во множественном числе.
Это подчеркивает природу переменной и делает код проще для анализа.
Получение данных
Элементы в списке упорядочены слева направо. Каждый элемент имеет порядковый номер, называемый индексом. Индексация списка начинается с нуля. То есть первый элемент списка доступен по индексу 0, второй — по индексу 1 и так далее. Для извлечения элемента из списка по индексу используется особый синтаксис:
animals = ['cats', 'dogs', 'birds']
animals[0] # 'cats'
animals[1] # 'dogs'
# Последний индекс в списке всегда меньше размера списка на единицу.
# В этом списке три элемента, но последний индекс равен двум
animals[2] # 'birds'
Узнать размер списка можно, с помощью функции len().
animals = ['cats', 'dogs', 'birds']
# У списков много других методов
len(animals) # 3
В реальных задачах индекс часто вычисляется динамически, поэтому обращение к конкретному элементу происходит с использованием переменных:
i = 1
animals = ['cats', 'dogs', 'birds']
animals[i] # 'dogs'
И даже так:
i = 1
j = 1
animals = ['cats', 'dogs', 'birds']
animals[i + j] # 'birds'
Такой вызов возможен по одной простой причине — внутри скобок ожидается выражение. А там, где ожидается выражение, можно подставлять все, что вычисляется. В том числе вызовы функций:
animals = ['cats', 'dogs', 'birds']
animals[len(['a', 'b'])] # 'birds'
В Python индексы можно указывать не только положительные, но и отрицательные. В таком случае отсчет происходит с конца списка. Довольно часто в задачах с использованием списков нужно взять последний элемент. В Python для этого достаточно лишь указать индекс элемента -1:
animals = ['cats', 'dogs', 'birds']
print(animals[-1]) # birds
Модификация
Примитивные типы данных невозможно изменять. Любые функции и методы над ними возвращают новые значения, но не могут ничего сделать со старым.
name = 'Python'
name.upper() # 'PYTHON'
# Значение name не поменялось
print(name) # 'Python'
Со списками это правило не работает. Списки могут меняться: увеличиваться, уменьшаться, изменять значения по индексам. Ниже разберем основные операции.
Изменение элементов списка
Синтаксис изменения элемента списка практически такой же, как и при обращении к элементу списка. Разница лишь в наличии присваивания:
animals = ['cats', 'dogs', 'birds']
# Меняется первый элемент списка
animals[0] = 'horses'
print(animals) # => [ 'horses', 'dogs', 'birds' ]
Добавление элемента в список
Метод append() добавляет элемент в конец списка:
animals = ['cats', 'dogs', 'birds']
animals.append('horses')
# Список animals изменен — стал больше
print(animals) # => [ 'cats', 'dogs', 'birds', 'horses' ]
# Строка 'horses' была добавлена в конец списка (индекс = 3)
print(animals[3]) # => 'horses'
Метод insert() добавляет элемент перед указанным по индексу элементом списка:
animals = ['cats', 'dogs', 'birds']
# Добавит элемент перед 2 индексом, то есть между 'dogs' и 'birds'
animals.insert(2, 'horses')
print(animals) # => ['cats', 'dogs', 'horses', 'birds']
Метод extend() расширяет список всеми элементами из переданного списка:
animals = ['cats', 'dogs']
birds = ['heron', 'sparrow', 'swift']
animals.extend(birds)
print(animals) # => ['cats', 'dogs', 'heron', 'sparrow', 'swift']
Новички часто совершают такую ошибку:
l = [1]
l = l.append(2)
print(l) # None
# A где список?
Нужно помнить, что определенные методы изменяют сам список, но возвращают None. Это избавит от потенциальных ошибок и удивления.
Удаление элемента из списка
Удалить элемент из списка можно с помощью оператора del.
animals = ['cats', 'dogs', 'birds']
# удаляем элемент под индексом 1
del animals[1]
print(animals) # => ['cats', 'birds']
Удалить элемент из списка можно также с помощью метода remove().
animals = ['cats', 'dogs', 'birds']
# удаляем элемент под индексом 1
animals.remove('dogs')
print(animals) # => ['cats', 'birds']
Проверка существования значения
При работе со списками часто допускается ситуация, называемая "выход за границу списка". Она возникает при обращении к несуществующему индексу:
animals = ['cats', 'dogs', 'birds']
# Элемента с индексом 5 не существует
animals[5] # IndexError: list index out of range
В разных языках программирования поведение в случае выхода за границу реализовано совершенно по-разному. Иногда возникает ошибка, иногда нет, а иногда подобный выход возвращает случайные данные из соседнего блока памяти, как в Си, что может привести к катастрофе.
animals = ['cats', 'dogs', 'birds']
# Выход за границы списка
animals[5] # IndexError: list index out of range
animals[4] # IndexError: list index out of range
animals[3] # IndexError: list index out of range
# Ура, мы попали в границы списка :)
animals[2] # 'birds'
В подавляющем большинстве ситуаций выход за границу списка является нежелательным поведением. Он происходит из-за логических ошибок в программе. При этом программа может работать и даже иногда выдавать правильный результат. Самый простой способ проверить выход за границу — это убедиться в том, что индекс меньше длины списка. Это можно сделать с помощью функции len():
animals = ['cats', 'dogs', 'birds']
index = 1
# Важно что <, а не <=.
# потому что такого индекса нет len(animals) = 3
if index < len(animals):
animal = animals[index] # все отлично!
print(animal) # => dogs
Попробуйте сами запустить код в окне ниже с интерпретатором Python и повторите примеры из статьи чтобы самим увидеть и понять как всё это работает. Для этого в ячейке с кодом нажмите клавиши на клавиатуре Shift+Enter или запустите код через кнопку Run по значку ▶.