Списки в Python: полное руководство для начинающих

Представьте, что вы собираетесь заехать за покупками в ближайший супермаркет. Что нужно сделать вначале? Верно! Составить список покупок. А в Python есть структура данных, очень напоминающая такие списки. Собственно, она так и называется — список (англ. list).

shopping list
shopping list

Это статья о списках в Python, предназначенная для начинающих. В следующие несколько минут мы познакомимся со списками и рассмотрим самые распространенные операции с ними: срезы и модификации при помощи методов списков.

Итак, давайте погрузимся в тему списков в Python, продолжая проводить аналогии со списками покупок.

Как работают списки

Составляя список покупок, мы записываем нужные нам товары в столбик. В таком виде список легко узнаваем именно как список покупок.

Чтобы Python понял, что имеет дело со списком, нужно заключить все элементы в квадратные скобки ([]). Сами элементы при этом разделяются запятыми.

Вот пример создания списка из 6 элементов (пускай это будут товары, которые мы хотим купить).

shopping_list = ['apples','pens','oatmeal cookies','notepad','brushes','paint']

Изменяемость списков в Python

Имея дело со списком покупок, мы свободно можем его изменять. Например, вычеркнуть овсяное печенье и добавить любимые конфеты. Точно так же можно изменять и списки в Python. Таким образом, списки — изменяемый тип данных.

Вот как можно заменить oatmeal cookies на candy:

shopping_list[2] = 'candy'
print(shopping_list)
# Вывод
>> ['apples', 'pens', 'candy', 'notepad', 'brushes', 'paint']

Индексация списков в Python

Вы заметили, что элемент oatmeal cookies идет в списке третьим, но чтобы его заменить, мы использовали индекс 2? Дело в том, что индексация начинается с нуля. В Python индекс — это по сути отступ от начала списка.

Первый элемент имеет индекс 0 (нет никакого отступа, элемент в самом начале списка). Второй элемент имеет индекс 1. И так далее. В общем, если в списке n элементов, последний из них будет иметь индекс (n-1).

Попытавшись обратиться к элементу по несуществующему индексу, мы получим ошибку — IndexError.

В нашем примере у нас есть список покупок из 6 элементов (диапазон индексов 0-5). Как показано в коде ниже, если мы попытаемся обратиться к элементу под индексом 6, мы получим ошибку, потому что элемента с таким индексом просто нет.

print(shopping_list[6])
# Вывод
>> --------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-21-a9f3b9517136> in <module>()
----> 1 shopping_list[6]

IndexError: list index out of range

С другой стороны, мы можем использовать отрицательные индексы. Последний элемент списка имеет индекс -1, предпоследний — -2 и так далее.

print(shopping_list[-1])
# Вывод
>> paint

Так же, как список покупок может содержать любые товары (фрукты, овощи, сладости и т. п.), список в Python может содержать элементы любого типа.

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

Вот пример вложенного списка покупок, содержащего два списка поменьше:

 my_nested_list = [['apple','banana'],['paint','brushes']]

Как перебирать список в цикле

Чтобы проверить, все ли мы купили, мы постоянно перечитываем список покупок. В программировании это называется «перебирать список». В Python списки перебираются в циклах, с использованием оператора in.

for item in shopping_list:
  print(item)
# Вывод 
apples
pens
candy
notepad
brushes
paint

Если бы нам нужно было не вывести элементы списка, а что-нибудь сделать с каждым из них, лучше было бы использовать range — чтобы получить индексы, а затем перебрать их в цикле.

Как делать срезы списков в Python

Что, если нам интересна лишь определенная часть нашего списка shopping_list? Тогда нам стоит взять его срез, чтобы получить нужную часть элементов.

Общий шаблон срезов таков:

 list_name[START:STOP:STEP]

Срез берется от индекса START (включительно) и до индекса STOP (не включая его), с шагом STEP. Каждый из параметров START, STOP, STEP может быть опущен.

  • Если нам нужно, чтобы в срез попал и последний элемент, индекс STOP нужно увеличить на единицу. Например, если у нас есть список list_name = ['apples', 'pens', 'candy', 'notepad', 'brushes', 'paint'] и нам нужен срез с элементами 'notepad', 'brushes' и 'paint' (индексы 3, 4, 5), срез будет выглядеть как list_name[3:6].
  • Индекс START по умолчанию — 0, а индекс STOP — индекс последнего элемента списка.
  • Если не указать START, срез начнется с первого элемента списка (под индексом 0).
  • Если не указать STOP, в срез попадут элементы от START до самого конца списка, включая последний элемент.
  • Ну а если не указать ни начальный, ни конечный индекс, срез вернет весь список целиком.

Давайте посмотрим на это в коде:

print(shopping_list[2:])
# Вывод
>> ['candy', 'notepad', 'brushes', 'paint']

print(shopping_list[:2])
# Вывод
>> ['apples', 'pens']

print(shopping_list[:])
# Вывод
>> ['apples', 'pens', 'candy', 'notepad', 'brushes', 'paint']

Операции со списками в Python

К спискам можно применить встроенные функции Python, такие как len(), min() и max(), чтобы получить длину списка, наименьший и наибольший элементы соответственно.

Поскольку наш shopping_list содержит только строки, min() возвращает строку, которая шла бы первой, если бы список был упорядочен в алфавитном порядке. max() возвращает строку, которая шла бы последней.

Посмотрим на это в коде:

print(len(shopping_list))
>> 6

print(max(shopping_list))
>> pens

print(min(shopping_list))
>> apples

Мы можем создавать новые списки, объединяя уже существующие — так же, как можем объединять списки покупок.

list_2 = shopping_list + ['noodles','almonds']
print(list_2)

>> ['apples', 'pens', 'candy', 'notepad', 'brushes', 'paint', 'noodles', 'almonds']

Методы списков в Python

Помимо уже названных встроенных функций Python имеет еще и несколько специальных методов для работы со списками. С помощью этих методов можно осуществлять разные полезные операции.

Давайте подумаем о списках покупок. Какие операции мы с ними проделываем чаще всего?

  • Добавляем элементы (по одному или несколько сразу)
  • Удаляем элементы
  • Меняем порядок элементов.

Как добавлять элементы в список

Мы можем добавлять элементы, вставляя их по одному в конец списка. Это делается при помощи метода append(). Давайте добавим grapes в наш shopping_list.

shopping_list.append('grapes')
print(shopping_list)

>> ['apples', 'pens', 'candy', 'notepad', 'brushes', 'paint', 'grapes']

Что, если бы мы захотели добавить в список элементы из другого списка (или другого итерируемого объекта)? Вместо того чтобы добавлять их по одному, мы можем воспользоваться методом extend() и добавить все элементы одного объекта в другой.

shopping_list.extend(['protein bars','cheese'])
print(shopping_list)

>> ['apples', 'pens', 'candy', 'notepad', 'brushes', 'paint', 'grapes', 'protein bars', 'cheese'

Примечание. Есть существенная разница между методами append() и extend() и оператором конкатенации +.

Оператор + создает новый список, комбинируя списки, указанные в качестве операндов. А методы append() и extend() изменяют список, для которого они вызваны, и не возвращают новых списков.

Как удалять элементы из списка

Мы можем удалять элементы из списка по одному или даже группами.

Метод pop() возвращает последний элемент списка и удаляет его, как показано ниже. Последним элементом в списке был cheese, а после применения метода pop() его не стало.

last_element = shopping_list.pop()
print(shopping_list)
print(last_element)
# Вывод
>> ['apples', 'pens', 'candy', 'notepad', 'brushes', 'paint', 'grapes', 'protein bars']
>> cheese

Если бы мы хотели удалить элемент под определенным индексом, этот индекс можно было бы передать в метод pop() в качестве аргумента.

not_needed = shopping_list.pop(2)
print(not_needed)
# Вывод
>> candy

Если нам не нужен доступ к значению удаляемого элемента, можно воспользоваться функцией del.

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

del shopping_list[1]
print(shopping_list)
# Вывод
>> ['apples', 'notepad', 'brushes', 'paint', 'grapes', 'protein bars']

Предположим, мы знаем, какой именно товар в списке покупок мы передумали покупать, но не знаем, какой у него индекс. В подобных случаях можно воспользоваться методом remove() и удалить элемент по значению.

В нашем примере элемент под индексом 1 — это pens. Если бы мы не знали индекс pens, мы могли бы просто написать shopping_list.remove('pens') и получить такой же результат, как в примере кода выше.

Для удаления всех элементов из списка можно использовать list_name.clear().

Примечание. При попытке удалить элемент, которого нет в списке, мы получим ValueError.

Сортировка списков в Python

Мы можем отсортировать shopping_list, вызвав метод sort(). Поскольку в нашем списке содержатся только строки, sort() отсортирует элементы по алфавиту. Если бы у нас был список чисел, по умолчанию элементы расположились бы в порядке возрастания.

При желании можно отсортировать список в порядке убывания, для этого нужно добавить опциональный аргумент reverse = True.

Примечание. Вызов метода sort() изменяет существующий список и не создает нового. Если вы хотите получить новый список с отсортированными элементами, а старый оставить в исходном состоянии, используйте метод sorted().

shopping_list.sort()
print(shopping_list)
# Вывод
>> ['apples', 'brushes', 'grapes', 'notepad', 'paint', 'protein bars']

Еще один полезный метод — count. С его помощью можно узнать, сколько раз определенный элемент встречается в списке. list_name.count(elt) вернет количество вхождений elt в список list_name.

Итоги

Из этой статьи вы узнали, как создавать списки, как брать срезы, как добавлять и удалять элементы из списков, а также — как сортировать списки.