for, range, enumerate и zip
Тема дорожной карты · Python Programming
Цикл for в Python обходит любой итерируемый объект, а не только числовой диапазон. Функция range(n) используется, когда вам нужны целочисленные индексы, а enumerate(seq) возвращает пары индекс-значение. Функция zip(a, b) позволяет одновременно итерироваться по нескольким последовательностям. Использование конструкции for i in range(len(seq)) — это стиль программирования на C, который следует избегать в Python. Также стоит помнить, что zip обрезает последовательности по самой короткой из них, а range возвращает ленивую последовательность, а не список.
Как это работает
Циклы for, функции range, enumerate и zip используются в сочетании с условными операторами if/elif/else, циклами for и while, а также с ключевыми словами break, continue, pass. С версии Python 3.10 стали доступны конструкции структурного соответствия match/case. В Python нет switch-оператора, идиоматичным способом управления несколькими условиями является использование цепочки if/elif. Цикл for итерирует объекты, которые поддерживают метод __iter__ (например, списки, генераторы, файлы), а цикл while продолжает выполняться до тех пор, пока условие не станет ложным (falsy). Также стоит отметить, что конструкции for ... else и while ... else выполняют блок else только в том случае, если цикл завершился без использования ключевого слова break. Это мощная, но редко используемая возможность Python.
Когда применять
Используйте цикл for, когда вам нужно итерироваться по известной последовательности. Он короче и менее склонен к ошибкам, связанным с бесконечными циклами. Структуры match/case предназначены для диспетчеризации по форме данных, например, для работы с tagged unions или узлами AST. Используйте enumerate(xs) и zip(xs, ys) вместо арифметики с индексами, так как это делает код более понятным и избавляет его от ошибок off-by-one.
Типичные ошибки
Типичные ошибки при использовании for, range, enumerate и zip включают проверку условия if x, когда на самом деле нужно проверить if x is not None (что приводит к одинаковому поведению для 0, "", []). Другая ошибка — это мутация списка при итерации (for x in xs: xs.remove(x)), что может привести к пропуску элементов. Также часто встречаются ошибки, связанные с использованием = вместо == в условиях (хотя синтаксически это ловится, но := walrus усложняет ситуацию). Наконец, чрезмерное использование try/except как способа управления потоком выполнения может замедлить выполнение программы и скрыть логику. Чтобы избежать этих ошибок, держите циклы короткими и чистыми, вынося тело цикла в отдельные функции.
Связанные понятия
Полезные ресурсы
Проверить знания (1)
Загрузка вопросов…