Циклы while и for, range, break и else
while
while повторяет тело, пока условие истинно:
n = 5
while n > 0:
print(n)
n -= 1
print("Пуск!")
Нажмите 👣 Пошагово — видно, как меняется n и проверяется условие.
Бесконечный цикл с выходом по условию:
#@stdin: 5 | 10 | стоп
total = 0
while True:
line = input("Число или «стоп»: ")
if line == "стоп":
break
total += int(line)
print("Сумма:", total)
Бесконечный цикл в курсе
Если код зациклился, через 6 секунд выполнение остановится автоматически — страница не зависнет.
for
for перебирает элементы любой коллекции (итерируемого объекта):
for fruit in ["яблоко", "груша", "слива"]:
print(fruit)
for ch in "abc":
print(ch, end=" ")
print()
for key in {"a": 1, "b": 2}: # по словарю — ключи
print(key)
range
range(start, stop, step) — последовательность целых чисел, stop не входит. Числа не хранятся в памяти, а вычисляются по требованию.
print(list(range(5)), list(range(2, 8)), list(range(0, 20, 5)), list(range(10, 0, -3)))
for i in range(3):
print("Повтор", i)
r = range(1_000_000_000)
print(len(r), r[123456], 999 in r) # мгновенно: range не создаёт миллиард чисел
enumerate и zip — вместо индексов
names = ["Анна", "Борис", "Вера"]
scores = [90, 75, 82]
# не по-питоновски:
for i in range(len(names)):
print(i, names[i])
# по-питоновски:
for i, name in enumerate(names, start=1):
print(i, name)
for name, score in zip(names, scores):
print(f"{name}: {score}")
zip останавливается на самом коротком списке. Чтобы получить ошибку при разной длине — zip(a, b, strict=True) (Python 3.10+).
break, continue, else
for n in range(1, 10):
if n % 2 == 0:
continue # пропустить чётные — сразу к следующей итерации
if n > 7:
break # выйти из цикла
print(n)
У циклов есть необычный else: он выполняется, если цикл не был прерван break. Удобно для поиска:
def find(items, target):
for i, item in enumerate(items):
if item == target:
print(f"Нашли {target} на позиции {i}")
break
else:
print(f"{target} не найден")
find([4, 8, 15], 8)
find([4, 8, 15], 16)
Как запомнить
Думайте об else у цикла как о «если не break» (nobreak).
Вложенные циклы
for i in range(1, 4):
for j in range(1, 4):
print(f"{i * j:3}", end="")
print()
break выходит только из внутреннего цикла. Чтобы выйти из нескольких, вынесите циклы в функцию и используйте return.
Не меняйте список во время перебора
nums = [1, 2, 2, 3, 2, 4]
for x in nums:
if x == 2:
nums.remove(x) # элементы «сдвигаются», и один из них пропускается
print(nums) # [1, 3, 2, 4] — одна двойка осталась!
nums = [1, 2, 2, 3, 2, 4]
nums = [x for x in nums if x != 2] # правильно: создать новый список
print(nums)
Перебирайте копию (for x in nums[:]) или стройте новый список. Для словаря изменение размера во время перебора вызывает RuntimeError.
Итог
while— пока условие истинно;while True+break— цикл с выходом из середины.forперебирает элементы;range(start, stop, step)— ленивая последовательность чисел.- Вместо индексов —
enumerateиzip. breakвыходит,continueпереходит к следующей итерации,elseу цикла — «если не было break».- Не изменяйте коллекцию, которую перебираете.
Практика решено 0 из 6
Напишите функцию fizzbuzz(n), которая возвращает список строк для чисел от 1 до n:
число, кратное 3, — "Fizz", кратное 5, — "Buzz", кратное 15, — "FizzBuzz", иначе само число строкой.
Классика собеседований.
Какие тесты проверяют код (4)
assert fizzbuzz(5) == ["1", "2", "Fizz", "4", "Buzz"] assert fizzbuzz(15)[-1] == "FizzBuzz" assert len(fizzbuzz(100)) == 100 assert fizzbuzz(0) == []
def fizzbuzz(n):
result = []
for i in range(1, n + 1):
if i % 15 == 0:
result.append("FizzBuzz")
elif i % 3 == 0:
result.append("Fizz")
elif i % 5 == 0:
result.append("Buzz")
else:
result.append(str(i))
return result
Какие числа выдаст range?
| 0 1 2 | 1 2 3 | 0 2 4 | 5 4 3 | ничего | |
|---|---|---|---|---|---|
range(3) |
|||||
range(1, 4) |
|||||
range(0, 6, 2) |
|||||
range(5, 2, -1) |
|||||
range(5, 2) |
Напишите функцию first_negative_index(nums): вернуть индекс первого отрицательного числа
или -1, если таких нет. Используйте enumerate.
Какие тесты проверяют код (4)
assert first_negative_index([3, 5, -2, -7]) == 2 assert first_negative_index([1, 2]) == -1 assert first_negative_index([]) == -1 assert first_negative_index([-1]) == 0
def first_negative_index(nums):
for i, x in enumerate(nums):
if x < 0:
return i
return -1
Когда выполняется блок else у цикла for?
Напишите функцию is_prime(n), которая проверяет, простое ли число (n — целое).
Достаточно проверять делители до квадратного корня из n.
Какие тесты проверяют код (5)
assert [x for x in range(20) if is_prime(x)] == [2, 3, 5, 7, 11, 13, 17, 19] assert is_prime(97) is True assert is_prime(1) is False assert is_prime(7919) is True assert is_prime(7917) is False
def is_prime(n):
if n < 2:
return False
i = 2
while i * i <= n:
if n % i == 0:
return False
i += 1
return True
Напишите функцию pairs_sum(a, b), которая принимает два списка одинаковой длины и
возвращает список попарных сумм. Используйте zip.
Какие тесты проверяют код (2)
assert pairs_sum([1, 2, 3], [10, 20, 30]) == [11, 22, 33] assert pairs_sum([], []) == []
def pairs_sum(a, b):
return [x + y for x, y in zip(a, b)]
Войдите, чтобы отмечать пройденные уроки.