Сообщить об ошибке.

Цикл for/in, перебор последовательности в Python.

Перебор элементов списка, множества, символов строки, ключей словаря.

Инструкция for в Python немного отличается от того, что можно использовать в C или Pascal. for в Python не перебирает арифметическую прогрессию чисел, например как в Pascal, не дает пользователю возможность определять шаг итерации и условие остановки, как C. Вместо этого инструкция for в Python перебирает элементы любой последовательности (список list, строку string, кортеж tuple, словарь dict или другого объекта, поддерживающего итерацию) в том порядке, в котором они появляются.

>>>
>>> # Поменяйте элементы списка
... words = ['cat', 'window', 'defenestrate']
>>> for w in words:
...     print(w, len(w))
... 
cat 3
window 6
defenestrate 12
>>>

Код, который изменяет коллекцию во время итерации по этой же коллекции, может привести к неожиданному результату, не тому, который вы хотели получить. Не делайте так НИКОГДА! Вместо этого обычно проще выполнить цикл над копией коллекции или создать новую коллекцию:

# итерация по копии
for user, status in users.copy().items():
    if status == 'inactive':
        del users[user]

# создание новой коллекции
active_users = {}
for user, status in users.items():
    if status == 'active':
        active_users[user] = status

Спецификация оператора for/in/else:

for_stmt :: = "for" target_list "in" expression_list ":" suite
              ["else" ":" suite]

Список выражений для перебора инструкцией for вычисляется один раз и должен давать объект поддерживающий итерацию. Итератор создается для результата expression_list. Каждый элемент из expression_list в свою очередь присваивается целевой переменной target_list, значение которой передается в блок кода внутри инструкции for. Затем код блока for выполняется один раз для каждого элемента. Когда элементы исчерпаны, что происходит сразу же, когда последовательность пуста или итератор вызывает исключение StopIteration, выполняется набор в предложении else, если он присутствует, и цикл завершается.

  • Оператор break: выполняется код внутри for до оператора break и завершает цикл без выполнения блока внутри else.
  • Оператор continue: выполняется код внутри for до оператора continue, пропускает оставшуюся часть кода в блоке for и продолжает работу со следующим элементом списка перебираемых выражений или с оператором else, если следующего элемента нет.

Применим оператор break и continue в коде for/in/else и посмотрим на их поведение. Будем создавать список четных чисел из последовательности чисел от 0 до 14.

lst = []
for item in range(15) :
    # если число 10 есть в списке
    if 10 in lst:
        # прерываем цикл, при этом блок else не выполнится
        break
    # остаток от деления элемента списка
    a = item % 2
    # если элемент списка не четный или равен 0
    if a != 0 or item == 0:
        # пропускаем оставшийся код
        continue
    # добавление числа в список
    lst.append(item)
else:
    print ("Напечатает, если убрать условие с break")

print(lst)
# Код выведет:
[2, 4, 6, 8, 10]

Цикл for выполняет назначения переменным в целевом списке. Это перезаписывает все предыдущие назначения этим переменным, включая те, которые были сделаны в блоке for-loop:

Пример:

for i in range(10):
    print(i)
    i = 5
    # это не повлияет на цикл for так как переменная i
    # будет перезаписана следующим итерируемым элементом

Имена в целевом списке не удаляются, когда цикл завершен, но если последовательность пуста, то код внутри цикла не будет выполнен.

Подсказка: встроенная функция range() возвращает итератор целых чисел, подходящий для эмуляции эффекта языка Pascal for i: = a to b do; например, list(range(3)) возвращает список [0, 1, 2].

Обратите внимание. Существует тонкость, когда последовательность, по которой проходит итерация, пытаются изменить внутри цикла. Существует внутренний счетчик, который используется для отслеживания того, какой элемент используется следующим, и он увеличивается на каждой итерации. Когда этот счетчик достигнет длины последовательности, цикл завершается. Это означает, что если код внутри цикла удаляет текущий (или предыдущий) элемент из последовательности, по которой идет итерация, следующий элемент будет пропущен, так как он получает индекс текущего элемента, который уже был обработан.

Аналогично, если код внутри цикла вставляет элемент в последовательность перед текущим элементом. Текущий элемент будет обработан снова на следующем этапе итерации. Это может привести к неприятным ошибкам, которых можно избежать, сделав временную копию с использованием фрагмента всей последовательности.

b = a[:]
for item in b:
    if item < 0: 
        a.remove(item)