Содержание
Цикл по переменной
Цикл по переменной (или с параметром) for
применяется в том случае, когда прежде выполнения инструкций тела цикла, становится известным количество шагов, которые должен выполнить этот цикл. Название цикла связано с тем, что в заголовке этого цикла всегда используется счетчик. Счетчику (i
) присваивается начальное значение (a
). В зависимости от языка, на каждом шаге цикла счетчик получает приращение (n
, целое или дробное). Цикл заканчивает свою работу, когда значение счетчика приобретает максимально допустимое значение (b
), определяемое в условии. Обычно блок-схема цикла изображается с помощью блока “модификация”:
Инструкция for
В python цикл по переменной реализует инструкция for
. Синтаксис этой инструкции выглядит необычным образом:
for переменная_счетчик in последовательность: инструкции_1 [else: инструкции_2]
Дело в том, что цикл for
в python предназначен для обхода последовательностей (англ. sequence) любого итерируемого типа.
Последовательность в for
можно определять явно или использовать по имени. Приведем пример, в котором последовательность определяется явно.
Задача 1. Вывести на экран все степени числа 2
от 1
до 10
.
p = 1 for i in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10): p *= 2 print('2 ^{:>3} = {:>4}'.format(i, p))
Вывод
2 ^ 1 = 2 2 ^ 2 = 4 2 ^ 3 = 8 2 ^ 4 = 16 2 ^ 5 = 32 2 ^ 6 = 64 2 ^ 7 = 128 2 ^ 8 = 256 2 ^ 9 = 512 2 ^ 10 = 1024
На каждом шаге цикла переменная i
поочередно принимает все значения элементов последовательности. Когда будет передано значение последнего элемента последовательности, итерации прекратятся и цикл завершит свою работу.
Так же, как и цикл while
, инструкция цикла for
имеет необязательный блок else
.
Функция range()
Чтобы расширить применение цикла for
на задачи не относящиеся к обработке последовательностей и, тем самым, сделать его более универсальным, в python разработан класс range
. Его назначение создавать произвольные целочисленные последовательности в виде прогрессий. Хотя в python и принято причислять range
к типу последовательностей, но, на самом деле, последовательности, созданные range()
, не являются таковыми. Дело в том, что range
определяет только правила построения последовательности, сами же элементы в памяти не сохраняются.
range()
, может быть использована как основа для создания настоящих последовательностей.Функция range()
может применяться с одним, двумя или тремя аргументами:
-
range(a)
– создается последовательность от0
доa - 1
–[0, a-1]
(a
– не входит); -
range(a, b)
– создается последовательность отa
доb
–[a, b)
(b
– не входит); -
range(a, b, n)
– создается последовательность отa
доb
–[a, b)
с шагомn
(b
– не входит, шаг может быть отрицательным).
for
и функции range()
приведены ниже:
for j in range(10): print(j, end=' ') print() for j in range(10, 100, 10): print(j, end=' ') print() for j in range(100, 50, -5): print(j, end=' ')
Вывод
0 1 2 3 4 5 6 7 8 9 10 20 30 40 50 60 70 80 90 100 95 90 85 80 75 70 65 60 55
Рассмотрим пример из учебника.
Задача 2. Дано целое n
и действительное a
. Вычислить an (целую степень действительного числа).
a = float(input('a = ')) n = int(input('n = ')) p = 1 for i in range(n): p = p * a else: print('{:}^{:} = {:.5f}'.format(a, n, p))
Вывод
a = 2.1 n = 5 2.1^5 = 40.84101
Блок-схема
В данной программе значение счетчика не используется. Переменная цикла i
проходит по всем элементам последовательности от 0
до n-1
. В результате, цикл сделает n
итераций и мы получим искомое значение степени.
range()
. Если вы измените в текущей итерации значение счетчика, то вы измените только копию элемента последовательности, а не сам его элемент. Количество шагов цикла зависит только от количества элементов в последовательности и равно этому значению.Часто значение счетчика используется в теле цикла для изменения какой-либо величины. Приведем пример с черепахой. В этой программе значение счетчика используется для изменения радиуса окружности на каждой итерации.
Задача 3. Построить в центре холста n
разноцветных окружностей с общим центром так, чтобы окружность меньшего радиуса находилась поверх окружности с большим радиусом. Радиус r
самой большой окружности ввести с клавиатуры.
import turtle as t from random import random, seed ##################### Параметры холста ###################### seed() w = t.Screen() w.reset() w.title('Окружности') w.bgcolor('black') w.setup(width = 600, height = 600, startx = -10, starty = 10) #################### Параметры черепахи ##################### t.speed(10) t.hideturtle() ###################### Решение задачи ####################### r = int(input('r = ')) # Радиус самой большой окружности n = int(input('n = ')) # Количество окружностей t.up() t.goto(0, -r) # Устанавливаем по центру t.down() for i in range(n): R = random() G = random() B = random() t.fillcolor(R, G, B) t.begin_fill() t.circle(r - 30 * i) # Рисуем окружность t.end_fill() t.up() # Переходим к следующей t.lt(90) t.fd(30) t.rt(90) t.down() w.exitonclick() t.mainloop()
Вложенные циклы for
Для вложенных циклов, работающих от счетчика, чаще всего применяется цикл for
, так как он представляет эту структуру в более компактной форме. Приведем простой пример.
Задача 4. Вывести таблицу умножения шестнадцатеричных чисел от 1
до 10
(1610).
for i in range(1, 17): for j in range(1, 17): print('{:>4X}'.format(i * j), end='') print()
Вывод
1 2 3 4 5 6 7 8 9 A B C D E F 10 2 4 6 8 A C E 10 12 14 16 18 1A 1C 1E 20 3 6 9 C F 12 15 18 1B 1E 21 24 27 2A 2D 30 4 8 C 10 14 18 1C 20 24 28 2C 30 34 38 3C 40 5 A F 14 19 1E 23 28 2D 32 37 3C 41 46 4B 50 6 C 12 18 1E 24 2A 30 36 3C 42 48 4E 54 5A 60 7 E 15 1C 23 2A 31 38 3F 46 4D 54 5B 62 69 70 8 10 18 20 28 30 38 40 48 50 58 60 68 70 78 80 9 12 1B 24 2D 36 3F 48 51 5A 63 6C 75 7E 87 90 A 14 1E 28 32 3C 46 50 5A 64 6E 78 82 8C 96 A0 B 16 21 2C 37 42 4D 58 63 6E 79 84 8F 9A A5 B0 C 18 24 30 3C 48 54 60 6C 78 84 90 9C A8 B4 C0 D 1A 27 34 41 4E 5B 68 75 82 8F 9C A9 B6 C3 D0 E 1C 2A 38 46 54 62 70 7E 8C 9A A8 B6 C4 D2 E0 F 1E 2D 3C 4B 5A 69 78 87 96 A5 B4 C3 D2 E1 F0 10 20 30 40 50 60 70 80 90 A0 B0 C0 D0 E0 F0 100
Блок-схема
Обратите внимание, что переменные внешнего и вложенного циклов должны иметь разные имена!
Вывод по образцу с помощью for
тоже возможен.
Задача 5. Вывести числовой треугольник по образцу:
1 2 1 3 2 1 4 3 2 1 5 4 3 2 1 6 5 4 3 2 1 7 6 5 4 3 2 1 8 7 6 5 4 3 2 1 9 8 7 6 5 4 3 2 1
for i in range(1, 11): for j in range(1, i): print('{:>3}'.format(i - j), end='') print()
Вывод см. выше
Здесь длина последовательности, создаваемой функцией range()
для вложенного цикла, будет зависеть от значения i
на текущей итерации.
Рассмотрим более сложный пример переборного алгоритма реализованного с помощью вложенных for
.
Задача 6. Вывести таблицу истинности для логического выражения:
not(a v b) v (a ^ c)
,
где a
, b
и c
– это логические переменные.
print('{:}{:>3}{:>3}{:>3}'.format('a', 'b', 'c', 'f')) for a in (0, 1): for b in (0, 1): for c in (0, 1): print('{:}{:>3}{:>3}{:>3}' .format(a, b, c, not(a or b) or a and c))
Вывод
a b c f 0 0 0 1 0 0 1 1 0 1 0 0 0 1 1 0 1 0 0 0 1 0 1 1 1 1 0 0 1 1 1 1
Как видите, мы оказались правы – переборные циклы выполненные с помощью for
выглядят значительно компактнее аналогичных c циклом while
.
Заметим, что цикл одного типа может быть вложен в цикл другого типа.
Задача 7. Найти натуральное число от 100
до 1000
с максимальной суммой делителей
max = 0 for j in range(100, 1001): s = 0 i = 2 while i <= j // 2: if j % i == 0: s += i i += 1 if s > max: max = s k = j else: print(k)
Вывод
960
Рассмотрим пример с черепахой, которая мостит треугольную плитку на холсте с помощью вложенных циклов for
.
Задача 8. Составить программу мощения черепахой равносторонней треугольной плиткой всей площади холста. Размер стороны плитки определить с клавиатуры.
import turtle as t from math import sqrt ##################### Параметры холста ###################### w = t.Screen() w.reset() w.title('Плитка') w.bgcolor('black') w.setup(width = 600, height = 600, startx = -10, starty = 10) #################### Параметры черепахи ##################### t.speed(10) t.hideturtle() t.goto(-300,300) ###################### Решение задачи ####################### d = int(input("Длина стороны -> ")) n = 600 // d # Определяем количество плиток m = 600 // int(d * sqrt(3)) # количество рядов for i in range(m + 1): for j in range(n + 1): # за один шаг рисуем 2 ряда t.fillcolor("DeepSkyBlue4") t.begin_fill() for k in range(3): t.fd(d) t.rt(120) t.end_fill() t.rt(60) t.fillcolor("dark turquoise") t.begin_fill() for k in range(3): t.fd(d) t.rt(120) t.end_fill() t.fd(d) t.fillcolor("dark turquoise") t.begin_fill() for k in range(3): t.fd(d) t.rt(120) t.end_fill() t.rt(60) t.fillcolor("DeepSkyBlue4") t.begin_fill() for k in range(3): t.fd(d) t.rt(120) t.end_fill() t.lt(180) t.fd(d) t.rt(60) t.bk((n + 1) * d) # Перемещаемся к следующему ряду t.rt(120) t.fd(d) t.lt(60) t.fd(d) t.lt(60) w.exitonclick() t.mainloop()
Вывод
d = 70
Замечаем, что в этой программе тоже наличествует повторяющийся код. На следующем уроке мы решим эту проблему.