Проверяет понимание различий между абстрактными типами Sequence и Iterable в системе аннотаций типов Python.
В системе типов Python (модуль typing) Iterable и Sequence представляют разные уровни абстракции для коллекций. Iterable — это самый общий контракт: объект, реализующий протокол итерации (метод __iter__() или __getitem__() с последовательными индексами). Sequence — это более строгий контракт, наследующий от Iterable, Reversible и Collection, который гарантирует поддержку доступа по индексу (__getitem__ с произвольным целым индексом), определение длины (__len__) и возможность обратной итерации.
from typing import Iterable, Sequence
def process_iterable(data: Iterable[int]) -> None:
for item in data:
print(item)
def process_sequence(data: Sequence[int]) -> None:
# Можем обратиться по индексу
first = data[0]
print(f"First element: {first}")
# Можем получить длину
print(f"Length: {len(data)}")
# Примеры вызовов
process_iterable([1, 2, 3]) # OK
process_iterable((x for x in range(3))) # OK, генератор
process_sequence([1, 2, 3]) # OK
process_sequence((1, 2, 3)) # OK, кортеж
# process_sequence((x for x in range(3))) # Ошибка типов: генератор не SequenceИспользуйте Iterable, если ваша функция только перебирает элементы и не требует доступа по индексу или длины. Это делает функцию более гибкой — она сможет принимать генераторы и другие ленивые последовательности. Используйте Sequence, когда вам нужен доступ по индексу, срезы или гарантия, что данные можно перебрать несколько раз (генераторы можно перебрать только один раз).
Вывод: Sequence — это более строгий и богатый тип, чем Iterable. Выбор между ними зависит от того, какие операции над коллекцией вы планируете выполнять. Для максимальной гибкости используйте Iterable, для гарантии доступа по индексу — Sequence.