Цикл for в языке Питон позволяет перебирать... почти всё, что угодно: объекты из списка, числа из арифметической прогрессии, элементы
списков, буквы слов и т.п.
В цикле for указывается переменная и множество значений, по которому будет пробегать переменная.
Множество значений может быть задано списком, кортежем, строкой или диапазоном.
Вот простейший пример использования цикла, где в качестве множества значений используется кортеж:
i = 1
for color in 'красный', 'оранжевый', 'жёлтый', 'зелёный', 'голубой', 'синий', 'фиолетовый':
print(i,'-й цвет радуги — это ', color, sep='')
i += 1
Эта программа выведет все цвета радуги:
1-й цвет радуги — это красный
2-й цвет радуги — это оранжевый
3-й цвет радуги — это жёлтый
4-й цвет радуги — это зелёный
5-й цвет радуги — это голубой
6-й цвет радуги — это синий
7-й цвет радуги — это фиолетовый
В этом примере переменная color последовательно принимает значения 'красный', 'оранжевый' и т.д.
В теле цикла выводится сообщение, которое содержит название цвета, то есть значение переменной color,
а также номер итерации цикла — число, которое сначала равно 1,
а потом увеличивается на один (инструкцией i += 1 с каждым проходом цикла).
В списке значений могут быть выражения различных типов, например:
for obj in 1, 2, 3, 'one', 'two', 'three':
print(obj)
При первых трёх итерациях цикла переменная i будет принимать значение типа int,
при последующих трёх — типа str.
Функция enumerate
Вернёмся к первому примеру.
В случаях, когда вместе с элементами нужны также и их индексы, идеоматический подход в питоне выглядит так:
for i, color in enumerate(('красный', 'оранжевый', 'жёлтый', 'зелёный', 'голубой', 'синий', 'фиолетовый')):
print(i + 1, '-й цвет радуги — это ', color, sep='')
Функция enumerate возвращает пары из порядкового номера элемента начиная с нуля и собственно самого элемента.
В данном примере ещё лучше воспользоваться параметром start, тогда нумерация начнётся не с нуля, а с указанного в параметре start значения:
for i, color in enumerate(('красный', 'оранжевый', 'жёлтый', 'зелёный', 'голубой', 'синий', 'фиолетовый'), start=1):
print(i, '-й цвет радуги — это ', color, sep='')
Функция range (повторы кода и числа от $0$ до $n-1$)
Очень часто циклы for используются либо для повторения какой-либо последовательности действий
заданное число раз, либо для прохода по нескольким последовательным числам.
Для повторения цикла некоторое заданное число раз n можно использовать цикл for
вместе с функцией range вот так:
А если нужно пройти по последовательным числам, то нужно просто использовать индексную переменную:
s = 0
for i in range(5):
print('i =', i, 'i² =', i * i)
s += i * i
print('0² + 1² + ... + 4² =', s)
i = 0 i² = 0
i = 1 i² = 1
i = 2 i² = 4
i = 3 i² = 9
i = 4 i² = 16
0² + 1² + ... + 4² = 30
В качестве n в range(n) может использоваться числовая константа, переменная или произвольное арифметическое
выражение (например, 2 ** 10).
Если значение n равно нулю или отрицательное, то тело цикла не выполнится ни разу.
Короткий код выше эквивалентен такому:
s = 0
# начало цикла
i = 0
print('i =', i, 'i² =', i * i)
s += i * i
i = 1
print('i =', i, 'i² =', i * i)
s += i * i
i = 2
print('i =', i, 'i² =', i * i)
s += i * i
i = 3
print('i =', i, 'i² =', i * i)
s += i * i
i = 4
print('i =', i, 'i² =', i * i)
s += i * i
# цикл окончен
print('0² + 1² + ... + 4² =', s)
Функция range (перебор членов арифметической прогрессии)
От $a$ до $b-1$
Вообще слово range означает дословно «диапазон» или «ряд».
Если написать её так:
for i in range(a, b):
Тело цикла
то индексная переменная i будет принимать значения от a до b - 1,
то есть числа от первого параметра до второго, но обязательно не включая второй.
Если же a ⩾ b, то цикл не будет выполнен ни разу.
Например, для того, чтобы просуммировать значения
чисел от 1 до n можно воспользоваться следующей программой:
sum = 0
for i in range(1, n + 1):
sum += i
В этом примере переменная i принимает значения 1, 2, ..., n, и значение переменной
sum последовательно увеличивается на указанные значения.
В порядке убывания и с произвольным шагом
Наконец, чтобы организовать цикл, в котором индексная переменная будет уменьшаться, необходимо использовать функцию range с тремя параметрами.
Первый параметр задаёт начальное значение индексной переменной, второй параметр — значение, до которого будет
изменяться индексная переменная (не включая его!), а третий параметр — величину изменения индексной переменной.
Например, сделать цикл по всем нечётным числам от 1 до 99 можно при помощи функции range(1, 100, 2), а сделать цикл по всем числам от 100 до 1 можно при помощи range(100, 0, -1).
Более формально, цикл for i in range(a, b, d) при d > 0 задаёт значения
индексной переменной i = a, i = a + d, i = a + 2 * d и так
для всех значений, для которых i < b. Если же d < 0, то переменная
цикла принимает все значения i > b.
Упражнения
A: Ряд — 1
Даны два целых числа A и B (при этом A≤B). Выведите все числа от A до B включительно.
1
5
1 2 3 4 5
IDE
B: Ряд — 2
Даны два целых числа A и В. Выведите все числа от A до B включительно, в порядке возрастания,
если A < B, или в порядке убывания в противном случае.
5
1
5 4 3 2 1
IDE
C: Ряд — 3
Напечатайте в порядке убывания 100 наименьших квадратов целых положительных чисел.
Программа ничего не получает на вход, только выводит нужные числа.
10000
9801
...
4
1
IDE
D: Ряд — 4
Дано натуральное число $n$. Напечатайте все $n$-значные нечетные натуральные
числа в порядке убывания.
1
9 7 5 3 1
IDE
Отладка (debugging) в PyCharm. Запуск и консоль
При написании программ очень часто оказывается, что программа работает неправильно.
И в ней нужно найти и исправить ошибку.
Ошибки являются неотъемлемой частью написания кода, поэтому нужно уметь их искать и исправлять.
PyCharm предоставляет очень удобные инструменты для отладки, и сейчас мы будем учиться их использовать.
Создайте файл с именем debug.py, скопируйте вот этот код и запустите:
n = -1
divisor = -1
for i in range(int(n ** 0.5)):
if n % i == 0:
divisor = i
break
if divisor < 0:
print('prime')
else:
print('divisor', divisor)
Запуск приведёт к примерно такой ошибке:
for i in range(int(n ** 0.5)):
^^^^^^^^^^^^^
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'complex'
Хм-м... Что-то про сложность...
Итак, давайте начинать дебажить.
Для этого кликните на номер строчки с кодом for i in range(int(n ** 0.5)):,
это добавит breakpoint — точку остановки отладки.
Если теперь нажать на характерную пиктограмму с жучком (горячая клавиша — Shift+F10),
то выполнение программы остановится перед выполнением этой строчки.
Кликайте на картинку, чтобы увеличить:
Вы увидите значения переменных прямо в коде, а также внизу, в окне «Debug»->«Threads & Variables».
Внизу также указываются типы значений переменных.
Ок, пока ещё не очень понятно.
Что-то в выражении int(n ** 0.5) работает неправильно.
И у нас есть возможность выяснить, что именно.
Для этого мы можем открыть консоль, после чего вводить туда значения и смотреть результат:
DBA: Debug. Запуск и консоль
Создайте файл с кодом из примера выше.
Поставьте breakpoint в строчке с циклом for.
Запустите отладку.
Откройте консоль.
Введите по очереди: n и n ** 0.5.
Сделайте скриншот и сдайте в тестирующую систему.
Должно получиться что-то такое.
Отладка (debugging) в PyCharm. Изменение значений на ходу.
Ок, неплохо.
Можно остановиться в любой момент остановиться и вычислить что угодно.
Более того, даже можно не писать руками нужные значения.
Можно выделить любой фрагмент кода (например, n ** 0.5) и нажать Alt+Shift+E (Execute selection in console),
и выделенный фрагмент кода будет выполнен в консоли.
Кроме изучения переменных, их можно даже менять.
Для этого нужно просто написать соответсвующее равенство в консоли.
После этого можно нажимать на «Step over» (хоткей — F8), чтобы дальше выполнять программу по шагам.
DBB: Debug. Изменение значений на ходу
Создайте файл с кодом из примера выше.
Поставьте breakpoint в строчке с циклом for.
Запустите отладку.
Откройте консоль.
Поменяйте значение числа n на 4.
Обратите внимание, значение переменной n в коде сразу поменялось.
Сделайте один шаг, чтобы выполнение остановилось на строчке с if.
Сделайте скриншот и сдайте в тестирующую систему.
Должно получиться что-то такое.
Отладка (debugging) в PyCharm. Остановка при исключениях.
Иногда программа падает по непонятной причине.
Очень удобно сразу посмотреть, чему были равны различные переменные в этот момент.
И в PyCharm'е это очень удобно делать.
Для этого нужно включить в настройках дебага остановку перед любым исключением.
Делаем клик правой кнопкой мыши на любой breakpoint (на красном кружочке слева), жмём More (или сразу хоткей Ctrl+Shift+F8).
Там ставим галочку на «Any exception» и на «Activation policy»->«On raise», затем — Done.
Теперь если ваша программа упадёт в режиме отладки, то сразу после возникновения ошибки отладка остановится,
и можно будет посмотреть, что происходило, а также поэксперементировать с переменными.
DBC: Debug. Остановка при исключениях
Настройте остановку отладки при выбрасывании ошибки как описано выше.
Замените в коде n = -1 на n = 4 и запустите отладку.
Отладка должна остановиться на строчке с if.
Сделайте скриншот и сдайте в тестирующую систему.
Должно получиться что-то такое.
Отладка (debugging) в PyCharm. Watches.
В программе выше range начинается с нуля, поэтому возникает деление на ноль.
Ок, поправим программу (теперь n = 25) и запустим:
n = 25
divisor = -1
for i in range(2, int(n ** 0.5)):
if n % i == 0:
divisor = i
break
if divisor < 0:
print('prime')
else:
print('divisor', divisor)
# prime
Программа говорит, что число 25 простое, хотя оно явно составное.
Но вроде же всё правильно: проверяем все делители от 2 до $\sqrt{n}$, что может пойти не так?
Одна из удобных фич — это watches — список значений, которые вычисляются и выводятся в окне с переменными на каждом шаге.
Если ввести какое-нибудь выражение в окне дебага в строке «Evaluate expression or add a watch» и нажать Ctrl+Shift+Enter (или значок с очками справа),
то это выражение будет вычиляться и отображаться на каждом шагу.
Кроме этого, если во время дебага кликнуть на стрелочку вниз справа от отображаемого во время отладки прямо в коде значения переменной,
то можно будет добавить inline watch — значение, которое отображается прямо в коде.
DBD: Debug. Watches
В программе выше замените n = 25 на n = int(input()).
Вводить значение для n во время отладки нужно будет в окне «Console».
Запустите отладку с n = 25.
Добавьте в watches выражения:
n ** 0.5, int(n ** 0.5) и n % i.
«Дошагайте» до i = 4, сделайте скриншот и сдайте в тестирующую систему.
Должно получиться что-то такое.
DBE: Debug. Conditional breakpoints
Для отладки есть ещё несколько полезных инструментов и кнопочек.
Они станут особенно полезны, когда дело дойдёт до функций.
Но именно эта фича — conditional breakpoints — помогает при дебаге больших циклов.
Научитесь ей пользоваться самостоятельно.
from hashlib import sha256
hasher = sha256()
for i in range(1000000):
hasher.update(str(i).encode())
final_hash = hasher.hexdigest()
print("Final hash:", final_hash)
Добавьте в watch выражение hasher.hexdigest() и остановите отладку при i = 179179.
Должно получиться что-то такое.
Обратите внимание: модифицировать программу (разбивать цикл на два, менять range или добавлять внутрь if) нельзя!
E: Сумма кубов
По данному натуральном $n$ вычислите сумму
\(1^3+2^3+3^3+...+n^3\).
3
36
★★
Это число можно вычислить и без суммирования.
Напишите в комментариях чему она равна и почему.
IDE
F: Сумма произведений соседних чисел
По данному натуральному $n$ вычислите сумму
$1\times2+2\times3+...+(n-1)\times n$.
4
20
2
2
IDE
G: Факториал
По данному целому неотрицательному $n$ вычислите значение $n!$.
5
120
★★★
Напишите программу, которая вычисляет 1,000,000! за одну минуту.
Не пытайтесь вывести это число (в нём около 5565709 десятичных цифр, и попытка вывода может занять больше 20 минут).
Чтобы проверить правильность ответа посмотрите на длину в двоичной записи.
Если ответ хранится в переменной x, то x.bit_length() = 18488885.
PS. Функцию factorial из модуля math разумеется нельзя использовать.
★★★★★
Напишите программу, которая вычисляет 1,000,000! за одну... секунду!.
Ну ладно, можно за пять :).
IDE
H: Сумма чисел от 1 до n
По данному натуральному $n\ge1$ вычислите сумму
$1+2+...+n$. Ответ выведите в виде
вычисленного выражение и его значения в точности, как показано в примере.
В этой задаче нельзя использовать if.
4
1+2+3+4=10
1
1=1
IDE
I: Сумма произведений соседних чисел — 2
По данному натуральному $n\ge2$ вычислите сумму
$1\times2+2\times3+...+(n-1)\times n$. Ответ выведите в виде
вычисленного выражение и его значения в точности, как показано в примере.
В этой задаче нельзя использовать if.
4
1*2+2*3+3*4=20
2
1*2=2
IDE
J: Четные числа
По данным двум натуральным числам A и B (A≤B) выведите все чётные числа на отрезке от A до B.
В этой задаче нельзя использовать инструкцию if.
1
10
2 4 6 8 10
IDE
K: Флаги
Напишите программу, которая по данному числу $n$ от 1 до 9 выводит на экран n флагов. Изображение одного флага
имеет размер 4×4 символов, между двумя соседними флагами также имеется пустой (из пробелов) столбец. Разрешается
вывести пустой столбец после последнего флага и вообще допускается вывод
пробелов в конце строк. Внутри каждого флага должен быть записан его номер — число от 1 до $n$.
Символ обратного слэша “\” в текстовых строках
имеет специальное значение. Чтобы включить в состав текстовой
строки такой символ, его нужно повторить дважды. Например,
для вывода на экран одного такого символа можно использовать
такой код: print("\\").
Дано 10 целых чисел. Считайте каждое из этих чисел и выведите столько символов “*”
чему равно это число. Выводите число сразу же после считывания числа.
Дано несколько чисел. Вычислите их сумму. Сначала вводите количество чисел N, затем вводится ровно N целых чисел.
Какое наименьшее число переменных нужно для решения этой задачи?
3
1
20
300
321
★
Какое наименьшее число переменных нужно для решения этой задачи (если не использовать никаких хаков)?
Напишите в комментариях сколько и почему.
IDE
N: Делители
По данному натуральному числу \(n\le 1000\) выведите все натуральные
делители числа \(n\) в порядке возрастания.
Числа нужно выводить в одной строке через пробел (вспомните про параметры
функции print).
10
1 2 5 10
IDE
O: Количество нулей
Дано N чисел: сначала вводится число N, затем вводится ровно N целых чисел. Подсчитайте количество
нулей среди введенных чисел и выведите это количество.
5
0
7
0
2
2
2
IDE
P: Цифры числа
Дано 10-значное число. Выведите все цифры этого числа в обратном порядке
по одной, без разделителей.
1234567890
0987654321
IDE
Q: Замечательные числа — 1
Найдите и выведите все двузначные числа, которые равны удвоенному произведению своих цифр.
Программа не требует ввода данных с клавиатуры, просто выводит список искомых чисел.
IDE
R: Замечательные числа — 2
Квадрат трехзначного числа оканчивается тремя цифрами, равными этому числу. Найдите и выведите все такие числа.
Программа не требует ввода данных с клавиатуры, просто выводит список искомых чисел.
IDE
S: Замечательные числа — 3
Дано натуральное число n. Выведите в порядке возрастания
все трехзначные числа, сумма цифр которых равна $n$.
3
102
111
120
201
210
300
IDE
T: Лесенка
По данному натуральному $n\le 9$ выведите лесенку из $n$ ступенек, $i$-я
ступенька состоит из чисел от 1 до $i$ без пробелов.
3
1
12
123
IDE
U: Замечательные числа — 4
Даны два четырёхзначных числа A и B. Выведите все четырёхзначные числа на отрезке от A до B, запись которых
является палиндромом.
1600
2100
1661
1771
1881
1991
2002
IDE
V: Замечательные числа — 5
Даны два четырёхзначных числа A и B.
Выведите в порядке возрастания все четырёхзначные числа на отрезке от A до B,
запись которых содержит ровно три одинаковые цифры.
1900
2100
1911
1999
2000
2022
IDE
W: Сумма факториалов
По данному натуральном \(n\) вычислите сумму \(1!+2!+3!+...+n!\).
В решении этой задачи можно использовать
только один цикл.
3
9
IDE
X: Домино
Рассмотрим \(N\)-домино. В таком домино каждая костяшка состоит из двух половинок, на каждой из которых нарисовано от 0 до \(N\) точек.
Полный комплект костяшек такого домино содержит все возможные костяшки, каждую по одному разу.
Например, для \(N=2\) в комплект войдут следующие костяшки: (0,0), (0,1), (0,2), (1,1), (1,2) и (2,2).
По заданному \(N\) (\(1\le N \le 30\)) определите, сколько всего точек изображено на всех костяшках полного комплекта \(N\)-домино.
Тесты к этой задаче закрытые.
2
12
IDE
Y: Треугольная последовательность
Дана монотонная последовательность,
в которой каждое натуральное число $k$ встречается ровно
$k$ раз: 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, ...
По данному натуральному $n$ выведите первые $n$ членов этой последовательности.
Решите задачу при помощи одного цикла for.
Операция умножения строки на число также не допускается.
2
1 2
5
1 2 2 3 3
IDE
Z: Остатки
Даны целые неотрицательные числа a, b, c, d, при этом
0≤c<d. Выведите в порядке возрастания все числа от a до b,
которые дают остаток c при делении на d.
В этой задаче нельзя использовать инструкцию if, операторы сравнения
(< и т.д.), должен быть только один цикл.
1
4
1
2
1 3
1
5
0
4
4
IDE
ZA★: Транспортные расходы
Необходимо заказать транспорт для перевозки \(N\) человек.
Заказывать можно автобусы и такси. В каждый автобус можно посадить не более 50 человек, в каждое такси — не более 4 человек.
Стоимость заказа автобуса составляет \(A\) рублей, такси — \(B\) рублей (разумеется, \(A \gt B\)).
Определите, какое количество автобусов и такси нужно заказать, чтобы потратить как можно меньшую сумму денег.
Программа получает на вход три целых числа: \(N\), \(A\), \(B\) (\(1 \le N \le 10^5\), \(1 \le B \lt A \le 1000\)).
Выведите два числа — количество автобусов и количество такси для заказа в оптимальном случае. Если возможных ответов несколько, выведите любой.
Тесты к этой задаче закрытые.
4
3
2
0 1
IDE
ZB★: Кривая дракона
Кривая дракона — один из наиболее известных фракталов. Она строится так:
на первом шаге проводится отрезок из начала координатной плоскости в точку (0; 1).
Далее на каждом шаге из конца фрактала повторяется уже нарисованная часть фигуры, повернутая на 90 градусов против часовой стрелки
По данному числу \(N\ge 1\) определите конец кривой дракона после выполнения \(N\) шагов.
Тесты к этой задаче закрытые.
2
1 1
4
2 -2
IDE
ZC★: Магический квадрат
Магический квадрат — это таблица 3×3,
в каждой из ячеек которой находятся числа от 0 до 9, числа могут повторяться,
но сумма чисел в каждой строке и каждом столбце равна одному числу \(N\).
Определите по данному \(N\) сколько существует различных магических квадратов
с суммой чисел в каждой строки и каждом столбце, равной \(N\).
Программа получает на вход одно целое неотрицательное число \(N\) и должна вывести искомое число вариантов.
0
1
1
6
IDE
ZD★★: Скорая помощь
Бригада скорой помощи выехала по вызову в один из отделенных районов. К сожалению,
когда диспетчер получил вызов, он успел записать только адрес дома и номер квартиры \(K_1\),
а затем связь прервалась. Однако он вспомнил, что по этому же адресу дома некоторое время назад
скорая помощь выезжала в квартиру \(K_2\), которая расположена в подъезде \(P_2\) на этаже \(N_2\).
Известно, что в доме \(M\) этажей и количество квартир на каждой лестничной площадке одинаково.
Напишите программу, которая вычилсяет номер подъезда \(P_1\) и номер этажа \(N_1\) квартиры \(K_1\).
Программа получает на вход пять положительных целых чисел \(K_1\), \(M\), \(K_2\), \(P_2\), \(N_2\).
Все числа не превосходят 1000.
Выведите два числа \(P_1\) и \(N_1\). Если входные данные не позволяют однозначно определить \(P_1\) или \(N_1\),
вместо соответствующего числа напечатайте 0. Если входные данные противоречивы, напечатайте два числа –1 (минус один).
Тесты к этой задаче закрытые.
89
20
41
1
11
2 3
11
1
1
1
1
0 1
3
2
2
2
1
-1 -1
IDE
ZE★: Страусиная ферма
На страусиной ферме есть \(N\times M\) птиц. Каждому страусу соорудили по загону, установив перегородки так, чтобы они образовывали прямоугольник из
\(N\) строк и \(M\) столбцов. Тем самым образуется ровно \(N\times M\) квадратных загонов \(1\times 1\).
В один прекрасный осенний день страус Чак, находившийся в нижнем левом загоне,
почувствовал острую необходимость отправиться по важным и неотложным страусиным делам.
Он начал пробивать себе путь на волю, ломая перегородки. Сначала он сломал правую перегородку
и переместился загоном правее. Потом он сломал верхнюю перегородку и переместился вверх.
Далее он прокладывал себе путь по такому же принципу: ломая попеременно то правую, то верхнюю перегородку, пока, наконец, не оказался на свободе.
Хозяин, увидев разгром, учиненный Чаком, сильно расстроился. Но делать нечего —надо приводить все в порядок.
Он отправил письмо на ближайшую лесопилку, указав, сколько у него осталось перегородок,
но забыв при этом указать, сколько ему требуется.
Помогите работникам лесопилки: зная, сколько у хозяина осталось перегородок, определите, каких размеров могла быть ферма.
Программа получает на вход одно число \(X\), \(1\le X\le 10^9\) — количество оставшихся перегородок.
Программа должна вывести все возможные варианты размеров фермы, в виде чисел \(N\) и \(M\), по одному варианту в строке. Порядок вывода вариантов не важен.