Знакомы ли вы с термином последовательность в Python
Что проверяют
Понимаете ли вы, что «последовательность» в Python это не бытовое «набор элементов», а конкретный протокол. Следом обычно спрашивают, является ли последовательностью словарь, множество или генератор, и чем последовательность отличается от просто итерируемого объекта.
Как отвечать
Последовательность это упорядоченная коллекция с доступом по целочисленному индексу и известной длиной. Формально это протокол из __getitem__ и __len__, а абстрактный класс collections.abc.Sequence по этим двум методам достраивает __contains__, __iter__, __reversed__, index и count.
- изменяемые:
listиbytearray. Для своих классов естьMutableSequence, который по базовым методам достраиваетappend,extend,pop,remove; - неизменяемые:
tuple,str,bytes,range.rangeне хранит элементы, а вычисляет их, поэтомуrange(10**9)занимает десятки байт; - операции: индексы, включая отрицательные, срезы
s[1:5]иs[::-1],in,len. Сцепление+и повторение*есть у списков, кортежей и строк, но не уrange.
Не являются последовательностями dict и set. Словарь хранит порядок вставки с версии 3.7, но по позиции не индексируется, это отображение. Генератор итерируемый, но тоже не последовательность: у него нет длины и индекса, и пройти его можно только один раз.
Для практики полезно знать аннотации. Если функция только читает данные, принимайте Sequence[int] из collections.abc: подойдут и список, и кортеж. И помните, что срез списка создаёт новый список, но копия поверхностная: вложенные объекты остаются общими.
Где спотыкаются
Называют последовательностью всё, что можно перебрать в for: словарь, множество, генератор. Перебор это признак итерируемого объекта, последовательность требует большего.
Забывают, что строка тоже Sequence[str]. Функция, которая ждёт список строк, молча примет одну строку и пройдётся по ней посимвольно.
Попадаются на [[0] * 3] * 3: повторение копирует ссылки, и все три строки матрицы оказываются одним списком. Правильно [[0] * 3 for _ in range(3)].