Цикл for

Вроде бы нам известен цикл while, зачем нам ещё и цикл for?

Возьмём код из предыдущей лекции, где мы просто печатали элементы массива:

array = [1, 2, 3, 0, 1.4, -2]
index = 0
while index < len(array):
    print(array[index])
    index = index + 1

Здесь есть несколько моментов, которые будут повторяться очень часто:

  • index = 0 - старт с нуля. +1 строка кода.
  • index < len(array) - закончить по достижении конца массива.
  • array[index] - получение значения элемента. Нам, как правило, не нужен номер элемента, нам нужно само значение (и в этой задаче это действительно так).
  • index = index + 1 - увеличение счётчика на 1. Ещё +1 строка кода.

Было бы здорово, если бы это всё выполнялось автоматически. Так вот, с циклом for это и делается автоматически! Посмотрите, как эта же задача решается при помощи цикла for:

array = [1, 2, 3, 0, 1.4, -2]
for element in array:
    print(element)

Размер кода уменьшился в 2 раза!

Но... что же делает этот код? Он проходит по каждому элементу последовательности, берёт его значение, и сохраняет в переменную.

Как же он понимает, что нужно делать? На самом деле, это синтаксический сахар. У многих объектов есть методы __iter__() и __next__(). Первый из них делает итерабельный объект (в большинстве случаев, это аналог сохранения index = 0). А второй вызывается много раз, и каждый раз он возвращает следующий элемент. И цикл for это (почти) аналог цикла while такого вида:

array = [1, 2, 3, 1, 1.4, -2]
iterable_object = iter(array)
while True:
    element = next(iterable_object)
    print(element)

При выполнении цикла while выше, вам встретится ошибка

Traceback (most recent call last):
  File "", line 7, in <module>
    element = next(iterable_object)
              ^^^^^^^^^^^^^^^^^^^^^
StopIteration

Это нормально, всё-таки я показал очень упрощённое преобразование for в while. Не зацикливайтесь на данном коде и ошибке.

Синтаксис цикла for уже показан полностью в примере:

for element in array:

array - это объект, поддерживающий протокол итерирования. На данный момент нам знакомы только списки, впоследствии мы познакомимся и с другими подобными типами.

in - ключевое слово, которое в данном контексте обозначает примерно "все элементы из array".

element - переменная, куда будет помещено значение элемента массива на каждой итерации. И да, каждую итерацию это будет следующий элемент последовательности, не нужно увеличивать никакой счётчик, как в цикле while (или как в языке Pascal).

Не следует изменять array внутри самого цикла! Это может привести к непредсказуемым результатам работы программы.

Внутри цикла for, как и внутри цикла while, можно использовать break, continue. Также есть возможность использовать блок else.

Например, дана задача: вывести первое положительные число в массиве, или написать, что положительных чисел нет.

array = [0, -3, -5, 4, -2, -3, 5, 6, 1]
for element in array:
    if element > 0:
        print(element)
        break
else:
    print("Положительных чисел нет")