← Назад к вопросам

Что будет с циклом for если проводить итерацию по списку?

1.0 Junior🔥 191 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Итерация по списку в цикле for: подробный разбор

Вопрос касается того, что происходит в цикле for при итерации по списку, особенно если список изменяется во время итерации.

1. Нормальная итерация (безопасный случай)

numbers = [1, 2, 3, 4, 5]

for num in numbers:
    print(num)  # Выведет: 1, 2, 3, 4, 5

В этом случае Python итерирует по каждому элементу списка последовательно.

2. Изменение списка ВНУТРИ цикла (опасно!)

numbers = [1, 2, 3, 4, 5]

for num in numbers:
    print(f"Обработка {num}")
    if num == 2:
        numbers.remove(num)  # Удаляем элемент

print(f"Результат: {numbers}")  # [1, 3, 4, 5]
# Результат может быть неожиданным!

Проблема: Python использует итератор, который отслеживает текущий индекс. Когда вы удаляете элемент, индекс сбивается, и некоторые элементы пропускаются.

numbers = [1, 2, 3, 4, 5]

for num in numbers:
    print(f"Обработка {num}")
    if num % 2 == 0:  # Удаляем четные
        numbers.remove(num)

print(f"Результат: {numbers}")
# Вывод:
# Обработка 1
# Обработка 3
# Обработка 5
# Результат: [1, 3, 5]
# Элементы 2 и 4 удалились, но 4 не был обработан!

3. Добавление элементов в список

numbers = [1, 2, 3]

for num in numbers:
    print(f"Обработка {num}")
    if num < 3:
        numbers.append(num * 10)

# Результат: Бесконечный цикл или неожиданное поведение!

4. Правильные подходы

Способ 1: Итерировать по копии списка

numbers = [1, 2, 3, 4, 5]

for num in numbers.copy():  # Итерируем по копии
    print(f"Обработка {num}")
    if num == 2:
        numbers.remove(num)  # Удаляем из оригинала

print(f"Результат: {numbers}")  # [1, 3, 4, 5] - корректно

Способ 2: List comprehension (рекомендуется)

numbers = [1, 2, 3, 4, 5]

# Фильтруем и переоформляем
numbers = [num for num in numbers if num != 2]
print(f"Результат: {numbers}")  # [1, 3, 4, 5]

Способ 3: Итерировать по индексам в обратном порядке

numbers = [1, 2, 3, 4, 5]

for i in range(len(numbers) - 1, -1, -1):  # От конца к началу
    if numbers[i] == 2:
        numbers.pop(i)

print(f"Результат: {numbers}")  # [1, 3, 4, 5]

Способ 4: filter() или другие встроенные функции

numbers = [1, 2, 3, 4, 5]

# Оставляем только нечетные
numbers = list(filter(lambda x: x % 2 != 0, numbers))
print(f"Результат: {numbers}")  # [1, 3, 5]

5. Как работает цикл for внутри?

numbers = [1, 2, 3]

# Цикл for работает через итератор:
iterator = iter(numbers)  # Создается итератор

while True:
    try:
        num = next(iterator)  # Получает следующий элемент
        print(num)
    except StopIteration:
        break

6. Безопасное добавление

numbers = [1, 2, 3, 4, 5]
to_add = []

for num in numbers:
    if num < 3:
        to_add.append(num * 10)

numbers.extend(to_add)  # Добавляем после цикла
print(f"Результат: {numbers}")  # [1, 2, 3, 4, 5, 10, 20]

Выводы:

  • Не изменяй список во время итерации! Это нарушает предсказуемость
  • Используй .copy() если нужна итерация по оригиналу
  • List comprehension — идеальное решение для фильтрации
  • Итерируй в обратном порядке, если нужно удалять элементы
  • Накапливай изменения и применяй их после цикла
  • Iterator protocol — основа работы цикла for
Что будет с циклом for если проводить итерацию по списку? | PrepBro