Python & AI Tutorials Logo
Программирование Python

12. Итерация с циклами for и range()

В главе 11 мы изучили циклы while, которые повторяют действия до тех пор, пока условие остаётся истинным. Хотя циклы while мощные и гибкие, они требуют, чтобы мы вручную управляли счётчиками цикла и обновляли условия. Python предоставляет другой тип цикла — цикл for — который отлично подходит для другой, но чрезвычайно распространённой задачи: обработка каждого элемента в коллекции данных по одному.

Цикл for — одна из наиболее часто используемых возможностей Python. Обрабатываете ли вы строки в файле, вычисляете статистики по последовательности чисел или проверяете каждый символ в строке, цикл for даёт чистый, читаемый способ проходить по последовательностям данных. В этой главе мы рассмотрим, как работают циклы for, как использовать функцию Python range() для операций подсчёта, а также как управлять выполнением цикла с помощью break, continue и менее известного блока else.

12.1) Цикл for и понятия итерации

12.1.1) Что такое цикл for?

Цикл for в Python повторяет блок кода один раз для каждого элемента в последовательности. Последовательностью может быть строка, список(list) (подробно мы изучим его в главе 14) или любая другая коллекция элементов. Ключевое отличие от цикла while в том, что цикл for автоматически выполняет итерацию — вам не нужно вручную обновлять счётчик или проверять условие.

Вот базовая структура цикла for:

python
for variable in sequence:
    # Блок кода, который выполняется для каждого элемента
    # Переменная хранит текущий элемент

Цикл for работает так:

  1. Python берёт первый элемент из последовательности и присваивает его переменной
  2. Выполняется блок кода (с отступом под оператором for)
  3. Python берёт следующий элемент, присваивает его переменной и снова выполняет блок
  4. Это продолжается, пока все элементы последовательности не будут обработаны

Рассмотрим простой пример со строкой:

python
# Вывести каждый символ в имени
name = "Alice"
for character in name:
    print(character)

Output:

A
l
i
c
e

В этом примере строка "Alice" — это последовательность. Цикл обрабатывает каждый символ по одному. Во время первой итерации character содержит 'A', во время второй — 'l' и так далее. Имя переменной character — наш выбор: мы могли назвать её letter, char или даже просто c. Выбирайте имена, которые ясно показывают назначение вашего кода.

Соглашения об именовании переменной цикла(loop variable): при написании циклов for выбирайте имена переменных, которые описывают, что представляет каждый элемент. Используйте описательные имена вроде character, student или score, когда значение важно для понимания кода. Используйте i для простых числовых счётчиков, когда вы просто считаете итерации. Используйте _ (подчёркивание), когда вам вообще не нужно значение — это соглашение Python, означающее «мне не важно это значение».

Вот практический пример, который считает гласные в слове:

python
# Посчитать гласные в слове
word = "Python"
vowel_count = 0
 
for letter in word:
    if letter in "aeiouAEIOU":
        vowel_count += 1
        print(f"Found vowel: {letter}")
 
print(f"Total vowels: {vowel_count}")

Output:

Found vowel: o
Total vowels: 1

Цикл проверяет каждую букву в "Python". Когда он находит гласную (используя оператор in, который мы изучили в главе 7), он увеличивает счётчик и печатает сообщение. Этот шаблон — инициализация счётчика перед циклом, а затем его обновление внутри — чрезвычайно распространён в программировании.

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

python
# Посчитать заглавные буквы в строке
text = "Python Programming"
uppercase_count = 0
 
for char in text:
    if char.isupper():
        uppercase_count += 1
 
print(f"Found {uppercase_count} uppercase letters in '{text}'")

Output:

Found 2 uppercase letters in 'Python Programming'

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

12.1.2) Понимание итерации

Итерация(iteration) — это процесс повторения действия для каждого элемента в коллекции. Когда мы говорим, что объект итерируемый(iterable), мы имеем в виду, что Python может обрабатывать его элементы по одному в цикле for. Строки итерируемы — мы можем проходить по их символам. Как мы скоро увидим, многие другие типы Python тоже являются итерируемыми.

Переменная в цикле for (например, character или letter в наших примерах) называется переменной цикла(loop variable). Эта переменная автоматически создаётся циклом for и существует только в области видимости цикла. Каждый проход цикла Python присваивает этой переменной следующий элемент из последовательности.

Вот пример, демонстрирующий, как изменяется переменная цикла:

python
# Показать, как обновляется переменная цикла
colors = "RGB"  # Red, Green, Blue
for color_code in colors:
    print(f"Processing color code: {color_code}")
    print(f"  This is iteration for '{color_code}'")

Output:

Processing color code: R
  This is iteration for 'R'
Processing color code: G
  This is iteration for 'G'
Processing color code: B
  This is iteration for 'B'

Каждый проход цикла color_code содержит разный символ из строки. Цикл автоматически переходит к следующему символу — нам не нужно писать код, чтобы продвигаться по последовательности.

12.1.3) Цикл for против while для итерации

Мы могли бы выполнить такую же посимвольную обработку с помощью цикла while, но для этого требуется больше кода и ручного управления:

python
# Использование цикла while для перебора строки (сложнее)
name = "Alice"
index = 0
while index < len(name):
    character = name[index]
    print(character)
    index += 1  # Нужно вручную обновлять индекс

Это даёт тот же вывод, что и наш предыдущий пример с циклом for, но обратите внимание, что нам пришлось сделать:

  • Создать и инициализировать переменную индекса
  • На каждой итерации проверять условие index < len(name)
  • Вручную извлекать символ через name[index]
  • Не забыть увеличить индекс (если забыть, получится бесконечный цикл!)

Цикл for делает всё это автоматически:

python
# Использование цикла for для перебора строки (проще)
name = "Alice"
for character in name:
    print(character)

Это намного чище и менее подвержено ошибкам. Цикл for — естественный выбор, когда вы хотите обработать каждый элемент в коллекции. Используйте цикл while, когда вам нужен больший контроль над логикой итерации или когда вы заранее не знаете, сколько раз нужно повторить.

Да

Нет

Старт цикла for

Получить следующий элемент из последовательности

Есть ещё элементы?

Присвоить элемент переменной цикла

Выполнить тело цикла

Выйти из цикла

12.2) Использование range() для циклов подсчёта

12.2.1) Знакомство с функцией range()

Хотя циклы for отлично подходят для обработки существующих последовательностей, нам часто нужно повторить действие строго определённое число раз — например, вывести сообщение пять раз или вычислить первые десять квадратов чисел. Функция Python range() генерирует последовательность чисел, по которой можно пройти циклом for.

Самая простая форма range() принимает один аргумент — количество целых чисел, которые нужно сгенерировать, начиная с 0:

python
# Вывести числа от 0 до 4
for number in range(5):
    print(number)

Output:

0
1
2
3
4

⚠️ Распространённая ошибка: новички часто ожидают, что range(5) даст 1, 2, 3, 4, 5, но на самом деле она выдаёт 0, 1, 2, 3, 4. Помните: range(n) начинается с 0 и останавливается перед n. Такое поведение «остановиться перед» согласуется со срезами Python, которые мы изучили в главе 5. Диапазон начинается с 0 (по умолчанию) и идёт до значения остановки, но не включая его.

Этот шаблон отлично подходит для повторения действия заданное число раз:

python
# Вывести приветствие пять раз
for i in range(5):
    print(f"Welcome! (iteration {i})")

Output:

Welcome! (iteration 0)
Welcome! (iteration 1)
Welcome! (iteration 2)
Welcome! (iteration 3)
Welcome! (iteration 4)

Переменная i — распространённое имя для счётчика цикла (сокращение от «index» или «iteration»), хотя вы можете использовать любое допустимое имя переменной. Когда значение переменной цикла не важно для вашей логики, i — традиционный выбор.

12.2.2) Задание значений start и stop

Можно передать два аргумента в range(), чтобы указать, где начать и где остановиться:

python
# Вывести числа от 1 до 5
for number in range(1, 6):
    print(number)

Output:

1
2
3
4
5

Здесь range(1, 6) начинается с 1 и останавливается перед 6, давая нам числа от 1 до 5. Это полезно, когда нужно считать, начиная не с нуля.

Используем это, чтобы вычислить простую таблицу умножения:

python
# Вывести таблицу умножения на 7 от 1 до 10
multiplier = 7
for number in range(1, 11):
    result = multiplier * number
    print(f"{multiplier} × {number} = {result}")

Output:

7 × 1 = 7
7 × 2 = 14
7 × 3 = 21
7 × 4 = 28
7 × 5 = 35
7 × 6 = 42
7 × 7 = 49
7 × 8 = 56
7 × 9 = 63
7 × 10 = 70

Цикл выполняется от 1 до 10, умножая каждое число на 7. Это демонстрирует, как range() упрощает выполнение вычислений по заданной числовой последовательности.

12.2.3) Использование шага

Функция range() принимает третий необязательный аргумент: значение шага(step), которое определяет, на сколько увеличивать (или уменьшать) число между значениями:

python
# Вывести чётные числа от 0 до 10
for number in range(0, 11, 2):
    print(number)

Output:

0
2
4
6
8
10

С range(0, 11, 2) мы начинаем с 0, останавливаемся перед 11 и увеличиваемся на 2 каждый раз. Это даёт нам все чётные числа от 0 до 10.

Также можно использовать отрицательный шаг, чтобы считать в обратную сторону:

python
# Обратный отсчёт от 10 до 1
for number in range(10, 0, -1):
    print(number)
print("Liftoff!")

Output:

10
9
8
7
6
5
4
3
2
1
Liftoff!

Здесь range(10, 0, -1) начинается с 10, останавливается перед 0 и уменьшает значение на 1 каждый раз. Отрицательный шаг заставляет диапазон считать назад.

Рассмотрим практический пример, который вычисляет сумму всех нечётных чисел от 1 до 100:

python
# Суммировать все нечётные числа от 1 до 100
total = 0
for number in range(1, 101, 2):  # Начать с 1, шаг 2
    total += number
 
print(f"Sum of odd numbers from 1 to 100: {total}")

Output:

Sum of odd numbers from 1 to 100: 2500

Используя range(1, 101, 2), мы генерируем только нечётные числа (1, 3, 5, ..., 99), избегая необходимости проверять чётность каждого числа внутри цикла. Это делает код более эффективным и ясным по смыслу.

12.2.4) Что на самом деле возвращает range()

Функция range() не создаёт список чисел в памяти — она создаёт объект range (range object), который генерирует числа по запросу. Это экономит память, особенно для больших диапазонов:

python
# range() возвращает объект range, а не список
numbers = range(1000000)
print(type(numbers))  # Output: <class 'range'>
print(numbers)        # Output: range(0, 1000000)

Output:

<class 'range'>
range(0, 1000000)

Хотя этот диапазон представляет миллион чисел, он использует очень мало памяти, потому что Python не создаёт все миллион чисел, пока вы не начнёте по нему итерироваться. Каждое число генерируется только тогда, когда оно нужно циклу.

Если вам нужен настоящий список чисел, можно преобразовать диапазон:

python
# Преобразовать range в список
small_numbers = list(range(5))
print(small_numbers)  # Output: [0, 1, 2, 3, 4]

Output:

[0, 1, 2, 3, 4]

Подробнее о списках и функции list() мы узнаем в главе 14. Пока просто знайте, что range() идеально работает с циклами for без какого-либо преобразования.

12.3) Итерация по строкам и другим последовательностям

12.3.1) Итерация по строкам посимвольно

Мы уже видели несколько примеров итерации по строкам. Это одно из самых распространённых применений циклов for, потому что строки — это последовательности символов, и нам часто нужно проверить или обработать каждый символ отдельно.

Вот пример, который проверяет пароль, убеждаясь, что он содержит хотя бы одну цифру:

python
# Проверить, содержит ли пароль хотя бы одну цифру
password = "secure123"
has_digit = False
 
for character in password:
    if character.isdigit():
        has_digit = True
        print(f"Found digit: {character}")
 
if has_digit:
    print("Password contains at least one digit ✓")
else:
    print("Password must contain at least one digit ✗")

Output:

Found digit: 1
Found digit: 2
Found digit: 3
Password contains at least one digit ✓

Цикл проверяет каждый символ с помощью строкового метода .isdigit() (который мы изучили в главе 5). Когда он находит цифру, он устанавливает has_digit в True. После завершения цикла мы проверяем флаг, чтобы определить, были ли найдены какие-либо цифры.

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

python
# Проанализировать типы символов в строке
text = "Hello, World! 123"
letters = 0
digits = 0
spaces = 0
other = 0
 
for char in text:
    if char.isalpha():
        letters += 1
    elif char.isdigit():
        digits += 1
    elif char.isspace():
        spaces += 1
    else:
        other += 1
 
print(f"Letters: {letters}")
print(f"Digits: {digits}")
print(f"Spaces: {spaces}")
print(f"Other: {other}")

Output:

Letters: 10
Digits: 3
Spaces: 2
Other: 2

Этот цикл классифицирует каждый символ, используя строковые методы, которые мы изучили в главе 5. Цепочка if-elif-else (из главы 8) гарантирует, что каждый символ будет учтён ровно в одной категории.

12.3.2) Обработка строк по индексам

Иногда нужно знать и символ, и его позицию в строке. Для итерации по индексам можно использовать range(len(string)):

python
# Найти позиции определённого символа
text = "Mississippi"
search_char = "s"
 
print(f"Looking for '{search_char}' in '{text}':")
for index in range(len(text)):
    if text[index] == search_char:
        print(f"  Found at index {index}")

Output:

Looking for 's' in 'Mississippi':
  Found at index 2
  Found at index 3
  Found at index 5
  Found at index 6

Цикл перебирает индексы от 0 до len(text) - 1. Для каждого индекса мы проверяем, совпадает ли символ в этой позиции с искомым. Такой подход полезен, когда важно знать, где именно что-то встречается, а не только факт наличия.

12.3.3) Итерация по другим типам последовательностей

Цикл for работает с любой итерируемой последовательностью в Python. Хотя в этой главе мы сосредоточились на строках, о других типах последовательностей вы узнаете в следующих главах. Например, в главе 14 вы изучите списки(list) — упорядоченные коллекции, которые могут хранить несколько значений любого типа. Синтаксис цикла for остаётся тем же независимо от того, по какому типу последовательности вы итерируетесь — цикл автоматически получает каждый элемент из последовательности.

12.4) Использование break и continue в циклах for

12.4.1) Оператор break в циклах for

Так же, как и в циклах while (глава 11), оператор break немедленно завершает цикл for, пропуская все оставшиеся итерации. Это полезно, когда вы нашли то, что искали, и больше не нужно продолжать поиск.

Вот пример, который ищет определённый символ:

python
# Найти первую гласную в строке
text = "Python"
found_vowel = False
 
for char in text:
    if char.lower() in "aeiou":
        print(f"First vowel found: {char}")
        found_vowel = True
        break  # Остановить поиск, как только найдём первую гласную
 
if not found_vowel:
    print("No vowels found")

Output:

First vowel found: o

Без break цикл продолжал бы проверять все оставшиеся символы даже после того, как нашёл первую гласную. Оператор break делает код более эффективным, останавливаясь сразу после завершения задачи.

Вот практический пример, который проверяет ввод пользователя, обнаруживая недопустимые символы:

python
# Проверить, что имя пользователя содержит только разрешённые символы
username = "alice_123"
allowed = "abcdefghijklmnopqrstuvwxyz0123456789_"
is_valid = True
 
for char in username:
    if char.lower() not in allowed:
        print(f"Invalid character found: '{char}'")
        is_valid = False
        break  # Нет смысла проверять дальше
 
if is_valid:
    print(f"Username '{username}' is valid ✓")
else:
    print(f"Username '{username}' is invalid ✗")

Output:

Username 'alice_123' is valid ✓

Цикл проверяет каждый символ на принадлежность разрешённому набору. Если он находит недопустимый символ, он сообщает о проблеме и сразу выходит из цикла — нет смысла проверять остаток имени пользователя, если мы уже знаем, что оно неверное.

12.4.2) Оператор continue в циклах for

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

Вот пример, который обрабатывает только определённые символы:

python
# Вывести только согласные из строки
word = "Programming"
 
for letter in word:
    if letter.lower() in "aeiou":
        continue  # Пропустить гласные
    print(letter, end="")
print()  # Новая строка в конце

Output:

Prgrmmng

Когда цикл встречает гласную, continue пропускает оператор print() и переходит к следующему символу. До печати доходят только согласные.

Вот более практический пример, который вычисляет статистику, пропуская неверные данные. Обратите внимание, что метод .split() (из главы 6) возвращает список(list) строк, о котором мы узнаем в главе 14. Пока просто знайте, что циклы for умеют перебирать результат:

python
# Вычислить среднее по корректным результатам теста (0-100)
# Метод .split() возвращает список строк (глава 14)
scores_input = "85 92 -5 78 105 90 88"
valid_scores = 0
total = 0
 
for score_str in scores_input.split():
    score = int(score_str)
    
    if score < 0 or score > 100:
        print(f"Skipping invalid score: {score}")
        continue  # Пропустить этот результат
    
    valid_scores += 1
    total += score
 
if valid_scores > 0:
    average = total / valid_scores
    print(f"Average of {valid_scores} valid scores: {average:.1f}")
else:
    print("No valid scores to average")

Output:

Skipping invalid score: -5
Skipping invalid score: 105
Average of 5 valid scores: 86.6

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

12.4.3) Когда использовать break и continue

Используйте break, когда:

  • Вы что-то ищете и хотите остановиться, как только найдёте
  • Вы столкнулись с ошибочным состоянием, из-за которого продолжать бессмысленно
  • Вы завершили задачу и не нужно обрабатывать оставшиеся элементы

Используйте continue, когда:

  • Вы хотите пропускать некоторые элементы по условию
  • Вы фильтруете данные и хотите обрабатывать только элементы, удовлетворяющие критериям
  • Вы хотите избежать глубоко вложенных if, обрабатывая особые случаи сразу

И break, и continue могут сделать код понятнее, явно показывая, когда и почему вы меняете нормальный ход итерации. Однако чрезмерное использование может ухудшить читаемость — применяйте их, когда они действительно улучшают ясность.

12.5) Использование else с циклами for

12.5.1) Шаблон for-else

Циклы for в Python поддерживают необязательный блок else, который выполняется после нормального завершения цикла — то есть когда цикл проходит по всем элементам и не встречает оператор break. Сначала это может показаться странным (почему «else», если нет «if»?), но это полезно, чтобы различать ситуации «нашёл то, что искал» и «просмотрел всё и не нашёл».

Вот базовая структура:

python
for item in sequence:
    # Тело цикла
    if some_condition:
        break
else:
    # Это выполняется только если цикл завершился без break
    print("Loop completed normally")

Блок else выполняется тогда и только тогда, когда цикл завершается естественным образом, исчерпав последовательность. Если оператор break завершает цикл раньше, блок else пропускается.

Рассмотрим практический пример поиска конкретного значения. Метод .split() (из главы 6) возвращает список(list) строк, о котором мы узнаем в главе 14:

python
# Поиск целевого числа
numbers = "2 4 6 8 10"
target = 7
 
for num_str in numbers.split():
    num = int(num_str)
    if num == target:
        print(f"Found {target}!")
        break
else:
    print(f"{target} not found in the sequence")

Output:

7 not found in the sequence

Цикл ищет среди всех чисел. Поскольку он никогда не находит 7, он завершается нормально, и выполняется блок else. Теперь поищем число, которое существует:

python
# Поиск целевого числа, которое существует
numbers = "2 4 6 8 10"
target = 6
 
for num_str in numbers.split():
    num = int(num_str)
    if num == target:
        print(f"Found {target}!")
        break
else:
    print(f"{target} not found in the sequence")

Output:

Found 6!

На этот раз, когда цикл находит 6, он выполняет break, который полностью пропускает блок else. Этот шаблон элегантно обрабатывает оба случая — «нашёл» и «не нашёл» — без необходимости в отдельной флаговой переменной.

12.5.2) Практические применения for-else

Шаблон for-else особенно полезен для операций поиска. Вот пример, который проверяет, состоит ли строка только из цифр:

python
# Проверить, является ли строка корректным целым числом
user_input = "12345"
 
for char in user_input:
    if not char.isdigit():
        print(f"Invalid: '{char}' is not a digit")
        break
else:
    print(f"'{user_input}' is a valid integer")

Output:

'12345' is a valid integer

Если ввод содержит хоть один нецифровой символ, цикл прерывается, и блок else не выполняется. Если все символы — цифры, цикл завершается нормально, и блок else подтверждает корректность.

Протестируем неверный ввод:

python
# Проверить, является ли строка корректным целым числом (неверный случай)
user_input = "123a5"
 
for char in user_input:
    if not char.isdigit():
        print(f"Invalid: '{char}' is not a digit")
        break
else:
    print(f"'{user_input}' is a valid integer")

Output:

Invalid: 'a' is not a digit

12.5.3) Сравнение for-else с флаговыми переменными

До знакомства с for-else вы могли использовать флаговую переменную, чтобы отслеживать, было ли что-то найдено:

python
# Использование флаговой переменной (традиционный подход)
text = "Python"
found_vowel = False
 
for char in text:
    if char.lower() in "aeiou":
        print(f"Found vowel: {char}")
        found_vowel = True
        break
 
if not found_vowel:
    print("No vowels found")

Output:

Found vowel: o

Шаблон for-else устраняет необходимость во флаговой переменной:

python
# Использование for-else (более Pythonic)
text = "Python"
 
for char in text:
    if char.lower() in "aeiou":
        print(f"Found vowel: {char}")
        break
else:
    print("No vowels found")

Output:

Found vowel: o

Оба подхода работают корректно, но вариант for-else более лаконичен и яснее выражает намерение: «ищи что-то, и если не найдёшь — сделай вот это». Блок else напрямую представляет случай «не найдено».

12.6) Выбор между циклами for и while

12.6.1) Когда использовать цикл for

Используйте цикл for, когда:

1. Вы обрабатываете каждый элемент в коллекции:

python
# Обработка каждого символа в строке
message = "Hello"
for char in message:
    print(char.upper())

Output:

H
E
L
L
O

2. Нужно повторить действие определённое число раз:

python
# Вывести линию-рамку
for i in range(40):
    print("-", end="")
print()

Output:

----------------------------------------

3. Вы итерируетесь по числовому диапазону:

python
# Вычислить факториал 5
factorial = 1
for n in range(1, 6):
    factorial *= n
print(f"5! = {factorial}")

Output:

5! = 120

4. Вы заранее знаете, по чему итерируетесь:

python
# Обработать известную последовательность значений
grades = "A B C D F"
for grade in grades.split():
    print(f"Grade: {grade}")

Output:

Grade: A
Grade: B
Grade: C
Grade: D
Grade: F

Ключевая характеристика циклов for в том, что они работают с определённой итерацией(definite iteration) — вы знаете, по какой последовательности итерируетесь, даже если заранее не знаете, сколько элементов она содержит.

12.6.2) Когда использовать цикл while

Используйте цикл while, когда:

1. Вы повторяете, пока условие не изменится:

python
# Продолжать спрашивать, пока не будет получен корректный ввод
while True:
    age_input = input("Enter your age: ")
    if age_input.isdigit():
        age = int(age_input)
        if age > 0:
            print(f"Age recorded: {age}")
            break
    print("Please enter a valid positive number")

2. Вы не знаете, сколько итераций понадобится:

python
# Посчитать, сколько раз можно удваивать число, прежде чем оно превысит 1000
number = 1
count = 0
while number <= 1000:
    number *= 2
    count += 1
print(f"Doubled {count} times to reach {number}")

Output:

Doubled 10 times to reach 1024

3. Итерация зависит от сложных условий:

python
# Смоделировать простую игру, где здоровье игрока уменьшается
health = 100
turn = 0
 
while health > 0 and turn < 10:
    damage = 15
    health -= damage
    turn += 1
    print(f"Turn {turn}: Health = {health}")
 
if health <= 0:
    print("Game over!")
else:
    print("Survived 10 turns!")

Output:

Turn 1: Health = 85
Turn 2: Health = 70
Turn 3: Health = 55
Turn 4: Health = 40
Turn 5: Health = 25
Turn 6: Health = 10
Turn 7: Health = -5
Game over!

4. Вам нужен больший контроль над логикой итерации:

python
# Обработать строку, но пропускать подряд идущие дубликаты
text = "bookkeeper"
index = 0
 
while index < len(text):
    char = text[index]
    print(char, end="")
    
    # Пропустить подряд идущие одинаковые символы
    while index < len(text) and text[index] == char:
        index += 1
 
print()

Output:

bokeper

Ключевая характеристика циклов whileнеопределённая итерация(indefinite iteration): вы продолжаете, пока условие не станет ложным, но можете заранее не знать, когда это произойдёт.

12.6.3) Преобразование между for и while

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

python
# Использование цикла for: сумма чисел от 1 до 10
total = 0
for number in range(1, 11):
    total += number
print(f"Sum (for loop): {total}")
 
# Использование цикла while: сумма чисел от 1 до 10
total = 0
number = 1
while number <= 10:
    total += number
    number += 1
print(f"Sum (while loop): {total}")

Output:

Sum (for loop): 55
Sum (while loop): 55

Оба дают одинаковый результат, но цикл for более лаконичен и менее подвержен ошибкам — нет риска забыть увеличить счётчик. Когда можно использовать оба, предпочитайте цикл for.

Однако некоторые задачи естественнее выражаются с помощью while:

python
# Найти первую степень двойки, большую 1000
power = 1
exponent = 0
 
while power <= 1000:
    exponent += 1
    power = 2 ** exponent
 
print(f"2^{exponent} = {power} (first power of 2 > 1000)")

Output:

2^10 = 1024 (first power of 2 > 1000)

Эта задача не очень естественно укладывается в цикл for, потому что мы заранее не знаем, сколько итераций потребуется — мы ищем значение, которое удовлетворяет условию.


В этой главе мы изучили цикл for в Python, который предоставляет чистый и мощный способ итерироваться по последовательностям. Мы узнали, как range() генерирует числовые последовательности для операций подсчёта, как управлять потоком выполнения цикла с помощью break и continue, и как шаблон for-else элегантно обрабатывает операции поиска. Мы также рассмотрели, когда выбирать циклы for вместо циклов while, исходя из характера вашей задачи итерации.

Цикл for — одна из наиболее часто используемых возможностей Python. Продолжая изучать Python, вы будете постоянно использовать циклы for — обрабатывая данные из файлов, работая со списками (lists) и словарями (dictionaries), и преобразуя коллекции информации. В следующей главе мы рассмотрим оператор Python match, который предоставляет ещё один способ принимать решения на основе значений, предлагая более структурированную альтернативу длинным цепочкам if-elif для определённых типов задач.


© 2025. Primesoft Co., Ltd.
support@primesoft.ai