Когда одного значения мало
Список list хранит упорядоченные элементы и допускает изменение. Индексы начинаются с нуля: у списка из n элементов допустимы 0 ... n - 1.append добавляет элемент в конец; len возвращает длину. Чтение через неверный индекс приводит к IndexError. Пустой список допустим, но у него нет первого элемента.
Кортеж tuple хранит последовательность, состав которой нельзя изменять. Множество set хранит уникальные значения, не обещая порядок обхода. Словарь dict сопоставляет ключу значение. Это разные контракты: не заменяйте список множеством, если повторы или порядок имеют значение.
Частоты
Для подсчёта повторений ключом словаря будет элемент, а значением — число встреч.counts.get(x, 0) возвращает прежнее число или ноль для отсутствующего ключа. После каждой обработки увеличьте его на один. В конце сумма всех частот должна равняться длине исходной последовательности — это полезная проверка.
Поиск в словаре и множестве обычно занимает ожидаемое O(1), но это не гарантия постоянного времени для любой операции и любого набора ключей. Проход списка линейный. Удаление первого элемента списка требует сдвигов; для очереди позже используйте deque.
Копия и общий объект
b = a связывает два имени с одним списком. b.append(7) изменит объект, видимый через a. b = a.copy() создаёт новый внешний список; вложенные изменяемые объекты при поверхностном копировании остаются общими. Для матрицы не пишите [[0] * m] * n: строки будут ссылаться на один список. Используйте отдельное создание каждой строки.
Сначала выберите, нужны ли порядок, повторения и поиск по ключу. Затем выберите коллекцию и проверьте пустой вход.