1.8. Списки

Список являются одним из самых используемых типов данных в языке Python. Если все ваше знакомство со списками ограничивается массивами в Visual Basic или (не дай бог) datastore в Powerbuilder, возмите себя в руки для знакомства со списками в языке Python.

Замечание
Списки в языке Python похожи на массивы в языке Perl. Имена пееменных, хранящих массивы, в языке Perl всегда начинаются с символа @. Python не накладывает никаких дополнительных ограничений на имя переменных, в которых хранятся списки, интерпретатор сам определяет тип переменной.
Замечание
Списки в языке Python — нечто большее, чем массивы в Java (хотя вы можете использовать их в таком качестве, если это все, что вам требуется от жизни). Более близкой аналогией будет класс Vector, способный содержать произвольные объекты и динамически увеличиваться при добавлении новых элементов.

Пример 1.14. Определение списков

>>> li = ["a", "b", "mpilgrim", "z", "example"] 1 >>> li ['a', 'b', 'mpilgrim', 'z', 'example'] >>> li[0] 2 'a' >>> li[4] 3 'example'
1 Сначала мы определяем список из пяти элементов. Обратите внимание, что исходный порядок элементов сохраняется. Это не случайно, список является упорядоченным множеством элементов, перечисленных в квадратных скобках.
2 Списки могут быть использованы в качестве массивов. Отсчет элементов всегда ведется от нуля, так что первый элемент непустого списка — li[0].
3 Последний элемент списка из пяти элементо — li[4], так как отсчет ведется от нуля.

Пример 1.15. Отрицательные индексы

>>> li ['a', 'b', 'mpilgrim', 'z', 'example'] >>> li[-1] 1 'example' >>> li[-3] 2 'mpilgrim'
1 При использовании отрицательных индексов отсчет ведется с конца списка. Послединий элемент любого непустого списка можно получить, используя выражение li[-1].
2 Если вас смущают отрицательные индексы, запомните простое правило: li[-n] == li[len(li) - n]. То есть, в нашем случае li[-3] == li[5 - 3] == li[2].

Пример 1.16. Срез

>>> li ['a', 'b', 'mpilgrim', 'z', 'example'] >>> li[1:3] 1 ['b', 'mpilgrim'] >>> li[1:-1] 2 ['b', 'mpilgrim', 'z'] >>> li[0:3] 3 ['a', 'b', 'mpilgrim']
1 Указав через двоеточие два индекса, вы можете получить подмножество элементов списка, называемое “срезом”. Получаемое значение является новым списком, содержащим все элементы исходного списка в том же порядке, начиная с первого индекса (здесь li[1]) до, но не включая, второго индекса (здесь li[3]).
2 В операции среза также можно использовать отрицательные идексы. Если это поможет, считайте первый индекс соответствующим первому элементу, который вам нужен, и второй — первому элементу, который не нужен. Получаемое значение — все, что между ними находится.
3 Нумерация элементов начинается с нуля, так что li[0:3] дает первые три элемента исходного списка.

Пример 1.17. Сокращения в записи среза

>>> li ['a', 'b', 'mpilgrim', 'z', 'example'] >>> li[:3] 1 ['a', 'b', 'mpilgrim'] >>> li[3:] 2 ['z', 'example'] >>> li[:] 3 ['a', 'b', 'mpilgrim', 'z', 'example']
1 Если первый индекс среза равен нулю, то его можно опустить. Аналогично можно опустить второй индекс, если он равен длине списка. То есть li[:3] дает такой же результат, как и li[0:3] в предыдущем примере.
2 Обратите внимание на симметрию. Для данного списка из пяти элементов li[:3] дает первые три элемента и li[3:] — последние два. В самом деле, li[:n] всегда дает первые n элементов, а li[n:] — все остальное.
3 Если опущены оба индекса, будут включены все элемента исходного списка. Но это не тот же список, это новый список с теми же элементами. Таким образом, li[:] позволяет создать копию списка.

Пример 1.18. Добавление элементов в список

>>> li ['a', 'b', 'mpilgrim', 'z', 'example'] >>> li.append("new") 1 >>> li ['a', 'b', 'mpilgrim', 'z', 'example', 'new'] >>> li.insert(2, "new") 2 >>> li ['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new'] >>> li.extend(["two", "elements"]) 3 >>> li ['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
1 Метод append добавляет один элемент в конец списка.
2 Метод insert вставляет один элемент в список. Целочисленный аргумент является индексом первого элемента, позиция которого изменится. Обратите внимание, что элементы списка могут быть не уникальными — после этой операции в списке содержится два элемента со значением "new", li[2] и li[6].
3 Метод extend добавляет в конец элементы другого списка. В данном случае второй список содержит два элемента.

Пример 1.19. Поиск в списке

>>> li ['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements'] >>> li.index("example") 1 5 >>> li.index("new") 2 2 >>> li.index("c") 3 Traceback (innermost last): File "<interactive input>", line 1, in ? ValueError: list.index(x): x not in list >>> "c" in li 4 0
1 Метод index находит первое вхождение элемента в списке и возвращает его индекс.
2 index позволяет найти только первое вхождение элемента. В нашем списке строка "new" присутствует дважды (li[2] и li[6]), но метод index вернет индекс только первого — 2.
3 Если указанный элемент в списке не найден, генерируется исключение. Такое поведение заметно отличается от поведения аналогичных средств в других языках, возвращающих какой-либо некорректный индекс. Генерация исключения более удобна, так как работа программы останавливается в месте возникновения ошибки, а не в момент использования некорректного индекса.
4 Для проверки наличия элемента в списке используйте оператор in, возвращающий 1, если значение найдено, и 0, если в списке такого значения нет.
Замечание
Python не имеет отдельного булева типа. В булевом контексте (например, в условии инструкции if), 0 является ложью, а все остальные сисла являются истиной. Аналогично и для других типов: пустая строка (""), список ([]) и словарь ({}) являются ложью, а все остальные строки, списки и словари — истиной.

Пример 1.20. Удаление элементов из списка

>>> li ['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements'] >>> li.remove("z") 1 >>> li ['a', 'b', 'new', 'mpilgrim', 'example', 'new', 'two', 'elements'] >>> li.remove("new") 2 >>> li ['a', 'b', 'mpilgrim', 'example', 'new', 'two', 'elements'] >>> li.remove("c") 3 Traceback (innermost last): File "<interactive input>", line 1, in ? ValueError: list.remove(x): x not in list >>> li.pop() 4 'elements' >>> li ['a', 'b', 'mpilgrim', 'example', 'new', 'two']
1 Метод remove удаляет из списка первый элемент с указанным значением.
2 remove удаляет только один элемент. В данном случае строка "new" присутствует в списке дважды, но li.remove("new") удалит только первую.
3 Если элемент с указанным значением в списке не найден, remove, как и index, генерирует исключение.
4 Метод pop выполняет сразу два действия: удаляет последний элемент из списка и возвращает его. Этим он отличается от li[-1], возвращающего последний элемент, но не изменяющего список, и li.remove(value), изменяющего список, но не возвращающего элемент.

Пример 1.21. Применение операторов к спискам

>>> li = ['a', 'b', 'mpilgrim'] >>> li = li + ['example', 'new'] 1 >>> li ['a', 'b', 'mpilgrim', 'example', 'new'] >>> li += ['two'] 2 >>> li ['a', 'b', 'mpilgrim', 'example', 'new', 'two'] >>> li = [1, 2] * 3 3 >>> li [1, 2, 1, 2, 1, 2]
1 С помощью оператора + можно “склеивать” списки. list = list + otherlist эквивалентно list.extend(otherlist), но при этом создается новый список, в то время как extend изменяет существующий.
2 Python поддерживает операцию +=. li += ['two'] полностью эквивалентно li.extend(['two']). Операция += работает для списков, строк, чисел и может быть переопределена для классов (более подробно о классах читайте в главе 3).
3 Оператор * размножает элементы списка. li = [1, 2] * 3 эквивалентно li = [1, 2] + [1, 2] + [1, 2].

Дополнительная литература