Как вы помните, элементы списков индексированы, т.е. каждый элемент имеет порядковый номер. Первый элемент имеет индекс 0
, последний — len(list) - 1
.
Функция
len
возвращает длину списка, но работает она с различными типами, например — со строками и кортежами.
Элементы списка можно получать и заменять через присваивание по их индексу. Если указать отрицательный индекс, то элементы будут браться с конца, и последний элемент списка будет иметь отрицательный индекс -1
(-0
, увы, использовать не получится). Вот пара примеров использования индексов со списком:
l = [0] * 3
l[0], l[1] = 10, 32
l[-1] = l[0] + l[1]
print(l) # => [10, 32, 42]
Обратите внимание, что я создал список клонированием нулей. Так делать безопасно, потому что числа в Python — неизменяемые. Впрочем, все модификации списка я сделал через присваивание, поэтому ничего неожиданного я бы не получил, даже если бы использовал изменяемые объекты.
pop
и insert
Итак, получать и заменять элементы по одному мы умеем. Неплохо бы ещё уметь удалять старые элементы и вставлять в середину списка новые. За это отвечают методы pop
и insert
соответственно. pop
удаляет элемент по индексу. Если не указать индекс, то удаляется последний элемент. При этом pop
возвращает значение элемента, который удаляет:
l = [1, 2, 3]
l.pop() # 3
print(l) # => [1, 2]
l.pop(0) # 1
print(l) # => [2]
А вот пример использования insert
:
l = [1, 2, 3]
l.insert(1, 100)
print(l) # => [1, 100, 2, 3]
l.insert(-1, 200)
print(l) # => [1, 100, 2, 200, 3]
insert
всегда вставляет новый элемент перед элементом с указанным индексом относительно начала списка, вне зависимости от того, откуда мы индекс отсчитывали — от начала или от конца. И insert(-1, ..)
вставляет элемент перед последним элементом!
Интересно, что
l.insert(len(l), x)
добавит элементx
в конец спискаl
, т.е. сработает какl.append(x)
. Фактически здесь не будет элемента, перед которым будет вставлен новый, вот новый элемент и попадёт в конец списка. Имейте в виду эту особенность, но используйтеappend
, хотя бы потому, что его вызов проще читается!
Если попытаться вызвать pop()
у пустого списка или указать индекс за пределами индексов существующих элементов, вы получите ошибку IndexError
:
l = []
l.pop()
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# IndexError: pop from empty list
А вот insert
более терпим к некорректным индексам и просто добавляет элементы с соответствующего края:
l = [0]
l.insert(-500, 1)
l.insert(1000, 2)
print(l) # => [1, 0, 2]
Однако полагаться на это не стоит — индексы всё же лучше держать под контролем!
Списки чего-либо периодически приходится сортировать, а иногда и разворачивать. Желательно уметь это делать эффективно. Поэтому список уже имеет встроенные средства для выполнения обеих задач — методы sort
и reverse
. Оба метода изменяют список по месту (in place). Посмотрим на несколько примеров:
l = [1, 3, 7, 2, 10, 8]
l.sort()
print(l) # => [1, 2, 3, 7, 8, 10]
l.reverse()
print(l) # => [10, 8, 7, 3, 2, 1]
Оба метода могут работать без параметров. В случае reverse
нечего и параметризовывать: разворачивание — это всегда разворачивание. А вот сортировка может производиться по разным критериям. Если вызывать sort
без параметров, то элементы сортируются в порядке возрастания. Однако методу можно передать параметр-функцию, которая будет возвращать критерий сортировки (т.н. ключ или key). Функция будет вызвана по одному разу для каждого элемента списка, после чего элементы будут отсортированы по возрастанию значения ключа. Давайте объявим функцию, которая будет возвращать остаток от деления аргумента на два, и используем её в роли ключа:
def mod2(x):
return x % 2
l = [1, 2, 3, 6, 5, 4]
l.sort(key=mod2)
print(l) # => [2, 6, 4, 1, 3, 5]
Обратите внимание, что функцию в метод
sort
я передал по имени параметра. Такой синтаксис мы рассмотрим позже, но поэкспериментировать с методомsort
и разными функциями-ключами вы уже сможете, указывая их по аналогии.
Функция mod2
вернула для чётных и нечётных чисел 0
и 1
соответственно. Поэтому в начале списка оказались сначала чётные числа.
Интересно, что в пределах своей группы числа сохранили порядок: 6
шла в списке перед 4
, и это взаимное расположение сохранилось. Умение сохранить относительный порядок элементов, которые уже отсортированы (относительно друг друга) — важная характеристика алгоритма сортировки! Называется она стабильностью, сортировка же в этом случае называется стабильной сортировкой — и в Python сортировка именно такая.
Функция-ключ не обязана возвращать числа — она может возвращать любые значения, которые Python умеет сравнивать. Давайте в предыдущем примере усложним функцию-ключ:
def key(x):
return (x % 2, x)
l = [1, 2, 3, 6, 5, 4]
l.sort(key=key)
print(l) # => [2, 4, 6, 1, 3, 5]
Теперь числа разбиты на группы и при этом ещё и отсортированы внутри групп! Когда Python сравнивает кортежи, он сравнивает сначала первые элементы, а если те равны — вторые и т.д. Значения сравниваются, пока не найдётся первое неравенство. Либо пока не кончится один из кортежей — в этом случае более короткий будет "меньше". Вот несколько примеров:
print((1, 2, 3) < (1, 2, 4)) # => True
print((1, 1) < (1, 1, 1)) # => True
print((1, 2) > (1, 1, 1)) # => True
print((3, 4, 5) == (3, 4, 5)) # => True
У меня нет цели рассказать про все доступные методы списков, я показываю лишь общие принципы. Я не рассказал про методы count
, remove
, index
: оставляю изучение этих методов вам. Напоминаю, посмотреть документацию можно прямо в REPL с помощью функции help
. Только для просмотра информации о методе объекта, нужно передавать метод вместе с объектом: help([].count)
.
Вам ответят команда поддержки Хекслета или другие студенты.
Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.
Загляните в раздел «Обсуждение»:
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.
Наши выпускники работают в компаниях:
С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.
Зарегистрируйтесь или войдите в свой аккаунт