Шаг 122.
Python: тонкости программирования. Общие структуры данных Python. Стеки (с дисциплиной доступа LIFO). list - простые встроенные стеки

    На этом шаге мы рассмотрим список с точки зрения организации стека.

    Встроенный в Python тип list создает нормальную стековую структуру данных, поскольку он поддерживает операции вталкивания и выталкивания за амортизируемое O(1) время.


См. документацию Python "Использование списков в качестве стеков": https://docs.python.org/3/tutorial/datastructures.html.

    На внутреннем уровне списки Python реализованы как динамические массивы, а значит, при добавлении или удалении элементов им время от времени нужно изменять пространство оперативной памяти для хранящихся в них элементов. Список выделяет избыточную резервную память, с тем чтобы не каждая операция вталкивания и выталкивания требовала изменения размера памяти, и, как результат, для этих операций вы получаете амортизируемую временную сложность O(1).

    Недостаток же состоит в том, что это делает показатели их производительности менее надежными, чем стабильные вставки и удаления с временной сложностью O(1), которые обеспечиваются реализацией на основе связного списка (такого, как collections.deque, см. следующий шаг). С другой стороны, списки реально обеспечивают быстрый (со временем O(1)) произвольный доступ к элементам в стеке, и это может быть дополнительным преимуществом.

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

    Чтобы получить производительность с амортизируемым временем O(1) для вставок и удалений, новые элементы должны добавляться в конец списка методом append() и снова удалятся из конца методом pop(). Для оптимальной производительности стеки на основе списков Python должны расти по направлению к более высоким индексам и сжиматься к более низким.

    Добавление и удаление элементов в начале списка намного медленнее и занимает O(n) времени, поскольку существующие элементы должны сдвигаться, чтобы создать место для нового элемента. Такого антишаблона производительности следует избегать.

>>> s = []
>>> s.append('есть')
>>> s.append('спать')
>>> s.append('программировать')
>>> s
['есть', 'спать', 'программировать']
>>> s.pop()
'программировать'
>>> s.pop()
'спать'
>>> s.pop()
'есть'
>>> s.pop()
Traceback (most recent call last):
.   .   .   .
IndexError: pop from empty list
')

    На следующем шаге мы рассмотрим класс collections.deque.




Предыдущий шаг Содержание