← Часть 8 Методы работы со множествами
Для выполнения повторяющихся, однотипных операций в программировании используются циклы. В Python таких циклов два:
for – счетный цикл, повторяется определенное количество раз ;
while – условный цикл, повторяется до выполнения определенного условия .
В этой статье мы разберем цикл for , а в следующей – while .
Назначение цикла for в Python
Цикл for используется в двух случаях:
Если нужно выполнить одну операцию (или набор из нескольких различных действий) определенное количество раз .
Если необходимо провести итерацию (перебор) элементов коллекции – списка, строки, словаря, кортежа, множества – одновременно выполняя какие-либо операции с этими элементами.
В любом из этих случаев цикл for может быть:
простым – состоящим из одного for -цикла;
вложенным – состоящим из двух и более for -циклов.
Кроме того, цикл может содержать:
простые и многоуровневые условия if… elif… else
;
оператор break
для прерывания и continue
для перехода к следующей итерации.
Каждый из этих вариантов мы рассмотрим ниже.
Структура простого цикла Python for
Простой цикл for выглядит так:
for название_переменной in range(число_повторений): тело цикла
Простейший пример такого цикла:
>>> for i in range(5): print('Python') Python Python Python Python Python
Другой пример простого цикла – перебор элементов какой-либо коллекции:
for название_переменной in название_коллекции: тело цикла
Код и результат работы подобного цикла выглядят так:
>>> for i in 'Python': print(i) P y t h o n
Первая строка, открывающая цикл for
, завершается двоеточием:
. Такие двоеточия используются во многих конструкциях Python, не только в for
, и каждый раз, обнаруживая :
, интерпретатор будет ожидать индентацию (отступ) на следующей строке. Отступы в Python разделяют код на логические блоки (в других языках такое разделение происходит с помощью иных знаков – фигурных скобок, точки с запятой). В соответствии с руководством PEP8, отступ может состоять либо из 4 пробелов , либо из одного символа табуляции Tab . Индентация пробелами – предпочтительна, табами – допустима. Однако недопустимо смешивать пробелы и табуляцию – это сразу же приведет к ошибке:
TabError: inconsistent use of tabs and spaces in indentation
Недостаток или избыток пробелов также приводят к ошибке, поскольку не дают интерпретатору определить, к какому именно логическому блоку относится фрагмент кода:
IndentationError: unindent does not match any outer indentation level
Структура вложенного цикла for
Любой цикл for может включать в себя другой for -цикл (или даже несколько):
lst1 = ['1', '2', '3', '4', '5'] lst2 = ['a', 'b', 'c', 'd', 'e'] for i in lst1: for j in lst2: print(i + j)
Во время выполнения вложенного цикла Python сначала перебирает все элементы внутреннего цикла, а затем переходит к следующему элементу внешнего цикла:
1a 1b 1c 1d 1e 2a 2b 2c 2d 2e 3a 3b 3c 3d 3e 4a 4b 4c 4d 4e 5a 5b 5c 5d 5e
Структура цикла for с условием
Для проверки соответствия переменных (элементов) каким-либо условиям в Python используется конструкция вида if… elif… else…
:
age = int(input('Сколько тебе лет? ')) if age < 7: print('В какой детсад ходишь?') elif 7 <= age <= 18: print('В какой школе учишься?') elif 18 <= age <= 23: print('Учишься в ВУЗе?') elif 60 <= age < 90 : print('Уже не работаешь?') elif age > 90: print('Долгожитель!') else: print('Где работаешь?')
Разумеется, при решении более простых задач условие может выглядеть гораздо проще:
st = 'abracad5bra' for i in st: if not i.isalpha(): print(i)
Структура цикла for с прерыванием break и пропуском continue
Иногда цикл нужно завершить досрочно в связи с обнаружением какого-либо значения или события. В этом случае используют оператор break
:
st = '32ey.5yhsf$h%owe82038e-3q0dwaefsfdgfhyfWfd9fG' for i in st: if i.isdigit() and int(i) > 8: break
Выполнение этого кода прервется, как только интерпретатор дойдет до цифры 9
в строке st
.
Помимо прерывания цикла, часто возникает необходимость не совершать операцию (или набор действий) для определенного элемента. Для этого используют оператор continue
, который переходит к следующей итерации при обнаружении элемента, который не следует обрабатывать:
st = 'м.у$т^а>б(о@р' for i in st: if not i.isalpha(): continue else: print(i)
Этот код пропускает все символы, которые не являются буквами. Результат:
м у т а б о р
Ввод и вывод данных с помощью цикла for в Питоне
Цикл for часто используют для ввода данных. Например, так можно ввести вложенный список (матрицу ) из n строк:
n = int(input()) lst = [] for i in range(n): lst.append(list(map(int, input().split())))
А так матрицу можно вывести:
# 1-й способ вывода for i in lst: print(*i) # 2-й способ вывода for i in range(len(lst)): for j in range(len(lst)): print(lst[i][j], end=' ') print() print()
Результат вывода матрицы из 5 строк:
1 2 3 4 7 7 8 3 9 0 1 3 9 5 3 2 7 4 9 2 1 9 0 4 5
Особенности цикла for в Python
1. В цикле for может быть более одной переменной. Например, так можно вывести на экран элементы словаря:
>>> my_dict = {'цвет': 'красный', 'артикул': 'ABC123', 'цена': 650} >>> for k, v in my_dict.items(): print(f'{k} - {v}') цвет - красный артикул - ABC123 цена - 650
2. Если переменная не используется в теле цикла, вместо названия можно указывать символ подчеркивания _
:
>>> mydict = {} >>> for _ in range(int(input())): k, v = input().split(': ') mydict[k.capitalize()] = v.title() 3 жанр: ужасы, триллер название: "мизери" автор: стивен кинг >>> print(mydict) {'Жанр': 'Ужасы, Триллер', 'Название': '"Мизери"', 'Автор': 'Стивен Кинг'}
3. В цикле for можно использовать дополнительные параметры функции range() – старт
и шаг
:
>>> for i in range(1, 12, 2): print('*' * i) * *** ***** ******* ********* ***********
4. Для проверки множества условий в цикле for очень удобно использовать словарь :
ops = {'-':'a - b', '+':'a + b', '*': 'a * b', '/':'a / b'} a, b = int(input('Введите значение a: ')), int(input('Введите значение b: ')) op = input('Введите знак операции: ') if op in ops.keys(): print(eval(ops[op])) else: print('Поддерживаются операции +, -, * и /')
Без словаря код выглядел бы так:
a, b = int(input('Введите значение a: ')), int(input('Введите значение b: ')) op = input('Введите знак операции: ') if op == '-': print(a - b) elif op == '+': print(a + b) elif op == '/': print(a / b) elif op == '*': print(a * b) else: print('Поддерживаются операции +, -, * и /')
5. Несмотря на то, что во многих случаях цикл for – простой, вложенный, с условиями – можно заменить генератором или списковым включением, обычный цикл читается легче – сравните эти примеры:
Генератор:
my_dict = {s[0].lower(): s[1] for s in (input().split(': ') for _ in range(int(input())))}
Обычный цикл for:
for _ in range(int(input())): k, v = input().split(': ') my_dict[k.lower()] = v
Кроме того, решение многих задач с помощью циклов выглядит более понятным и интуитивным – сравните цикл и генератор для вычисления ряда Фибоначчи :
Цикл + кортежи:
f1, f2 = 1, 1 for i in range(int(input())): print(f1) f1, f2 = f2, f1 + f2
Генератор Фибоначчи:
fib = [1, 1] calc = [fib.append(fib[i - 1] + fib[i - 2]) for i in range(2, int(input()))] print(*fib)
6. Вложенные циклы делают код для ввода и вывода матриц (вложенных списков) довольно объемным. Предположим, что нужно написать программу для ввода и вывода матрицы n x m . При n = 4 и m = 3 результат вывода выглядит так:
2 5 6 1 7 8 9 0 3 4 7 5
Сравним код ввода и вывода, написанный с применением вложенных циклов и код, реализованный с помощью генератора:
Вложенные циклы:
n, m = int(input()), int(input()) matrix = [] for i in range(n): matrix.append([]) for j in range(m): temp = input() matrix[i].append(temp) for i in range(n): for j in range(m): print(matrix[i][j], end=' ') print()
Генератор:
n, m = int(input()), int(input()) matrix = [[input() for word in range(m)] for _ in range(n)] [print(*i) for i in matrix]
7. Хотя генераторы и списковые включения являются, по сути, сжатой формой записи цикла, в синтаксисе циклов и генераторов есть различия. Например, в генераторax и списковыx включениях, в отличие от циклов, не используются операторы break
и continue
– вместо этого условие формулируется по-другому:
Цикл:
st = input() sp = [] for i in st: if i.isalpha(): sp.append(i) else: continue print(sp)
Генератор:
sp2 = [i for i in st if i.isalpha()] print(sp2)
8. Для параллельной итерации вместо вложенного цикла удобнее использовать простой for вместе с функцией zip() :
>>> list1 = ['а', 'б', 'в', 'г', 'д'] >>> list2 = [1, 2, 3, 4, 5] >>> for i, j in zip(list1, list2): print(i + str(j)) а1 б2 в3 г4 д5
Другой способ параллельной итерации – использование индекса одного из списков. Для обращения к индексам в range() включают функцию len() :
>>> lst1 = ['a', 'b', 'c', 'd', 'e'] >>> lst2 = [11, 12, 13, 14, 15] >>> for i in range(len(lst1)): print(lst1[i], lst2[i]) a 11 b 12 c 13 d 14 e 15
9. Для работы с индексами в цикле часто используется функция enumerate() :
>>> my_list = ['хард-рок', 'хэви-метал', 'хип-хоп', 'рэп', 'панк-рок'] >>> for i, j in enumerate(my_list): print(i, j) 0 хард-рок 1 хэви-метал 2 хип-хоп 3 рэп 4 панк-рок
10. При решении задач в циклах часто используют счетчики . Так, например, можно подсчитать количество отрицательных чисел:
lst = [5, 6, -3, 1, 12, -2, -7, 8, 3, 2] k = 0 for i in lst: if i < 0: k += 1 print(f'Количество отрицательных чисел: {k}')
Результат:
Количество отрицательных чисел: 3
Практика
Задание 1
Напишите программу, которая получает от пользователя число n и выводит n строк с результатом умножения чисел от 1 до n на символ * .
Пример ввода:
7
Вывод:
Умножаю * на 1: * Умножаю * на 2: ** Умножаю * на 3: *** Умножаю * на 4: **** Умножаю * на 5: ***** Умножаю * на 6: ****** Умножаю * на 7: *******
Решение:
n = int(input()) for i in range(1, n + 1): print(f"Умножаю * на {i}: {'*' * i}")
Задание 2
Напишите программу, которая получает от пользователя строку целых чисел, и выводит:
Количество положительных чисел.
Произведение всех отрицательных чисел.
Минимальное и максимальное числа без использования функций min() и max() .
Пример ввода:
3 -5 2 4 12 7 3 4 6 9 25 -50 12 35 2 11
Вывод:
Количество положительных чисел: 14 Произведение отрицательных чисел: 250 Минимальное число: -50 Максимальное число: 35
Решение:
lst = map(int, input().split()) pos = 0 neg_prod = 1 min_num = 0 max_num = 0 for i in lst: if i > 0: pos += 1 elif i < 0: neg_prod *= i if i < min_num: min_num = i elif i > max_num: max_num = i print(f'Количество положительных чисел: {pos}') print(f'Произведение отрицательных чисел: {neg_prod}') print(f'Минимальное число: {min_num}') print(f'Максимальное число: {max_num}')
Задание 3
Напишите программу, которая создает вложенный список из n строк, полученных от пользователя, и выводит сумму и произведение элементов каждого подсписка (без использования sum() и math.prod() ).
Пример ввода:
6 4 5 6 7 8 2 1 3 9 8 6 4 3 2 6 9 7 6 3 2 1 4 5 7 2 7 3 2 1 6
Вывод:
Подсписок 0: сумма чисел = 30, произведение = 6720 Подсписок 1: сумма чисел = 53, произведение = 2903040 Подсписок 2: сумма чисел = 74, произведение = 2508226560 Подсписок 3: сумма чисел = 101, произведение = 5688657838080 Подсписок 4: сумма чисел = 120, произведение = 1592824194662400 Подсписок 5: сумма чисел = 139, произведение = 401391697054924800
Решение:
n = int(input()) lst = [] for i in range(n): lst.append(list(map(int, input().split()))) summa = 0 prod = 1 for i, j in enumerate(lst): for num in j: summa += num prod *= num print(f'Подсписок {i}: сумма чисел = {summa}, произведение = {prod}')
Задание 4
Напишите программу, которая получает от пользователя строку текста и число n , а затем выводит вложенный список, в котором n последовательных элементов принадлежат разным подспискам.
Пример ввода:
абвгдеёжзийклмнопрстуфхцчшщъыьэюя 9
Вывод:
[['а', 'и', 'с', 'ъ'], ['б', 'й', 'т', 'ы'], ['в', 'к', 'у', 'ь'], ['г', 'л', 'ф', 'э'], ['д', 'м', 'х', 'ю'], ['е', 'н', 'ц', 'я'], ['ё', 'о', 'ч'], ['ж', 'п', 'ш'], ['з', 'р', 'щ']]
Решение:
st = list(input()) n = int(input()) result = [] for i in range(n): result.append(st[i::n]) print(result)
Задание 5
Напишите программу для транспонирования квадратной матрицы.
Пример ввода:
5 1 4 7 8 9 3 5 6 1 0 8 2 4 7 2 8 1 0 3 6 5 4 9 1 2
Вывод:
1 3 8 8 5 4 5 2 1 4 7 6 4 0 9 8 1 7 3 1 9 0 2 6 2
Решение:
n = int(input()) matrix = [input().split() for _ in range(n)] for i in range(n): for j in range(i, n): matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j] for i in matrix: print(*i)
Задание 6
Напишите программу, которая выводит на экран снежинку размера n x n . Элементы снежинки состоят из символов * , фон – из точек.
Пример ввода:
15
Вывод:
* . . . . . . * . . . . . . * . * . . . . . * . . . . . * . . . * . . . . * . . . . * . . . . . * . . . * . . . * . . . . . . . * . . * . . * . . . . . . . . . * . * . * . . . . . . . . . . . * * * . . . . . . * * * * * * * * * * * * * * * . . . . . . * * * . . . . . . . . . . . * . * . * . . . . . . . . . * . . * . . * . . . . . . . * . . . * . . . * . . . . . * . . . . * . . . . * . . . * . . . . . * . . . . . * . * . . . . . . * . . . . . . *
Решение:
n = int(input()) snowflake = [['.'] * n for _ in range(n)] for i in range(n): for j in range(n): if i == n // 2 or j == n // 2: snowflake[i][j] = '*' elif i == j or i + j + 1 == n: snowflake[i][j] = '*' for line in snowflake: print(*line)
Задание 7
Напишите программу, которая:
создает квадратную матрицу из полученных на вход строк;
проверяет, является ли матрица симметричной относительно побочной диагонали;
выводит Да
или Нет
в зависимости от результата.
Пример ввода:
4 1 2 3 1 2 2 2 3 3 3 2 2 4 3 2 1
Вывод:
Да
Решение:
n = int(input()) matrix = [] for _ in range(n): matrix.append(list(map(int, input().split()))) ans = 'Да' for i in range(n - 1): for j in range(n - i - 1): if matrix[i][j] != matrix[n - j - 1][n - i - 1]: ans = 'Нет' break if ans == 'Нет': break print(ans)
Задание 8
Напишите программу, которая получает от пользователя число 1 <= n <= 9 , и выводит таблицу умножения для всех чисел от 1 до n .
Пример ввода:
5
Вывод:
1 * 1 = 1 1 * 2 = 2 1 * 3 = 3 1 * 4 = 4 1 * 5 = 5 1 * 6 = 6 1 * 7 = 7 1 * 8 = 8 1 * 9 = 9 2 * 1 = 2 2 * 2 = 4 2 * 3 = 6 2 * 4 = 8 2 * 5 = 10 2 * 6 = 12 2 * 7 = 14 2 * 8 = 16 2 * 9 = 18 3 * 1 = 3 3 * 2 = 6 3 * 3 = 9 3 * 4 = 12 3 * 5 = 15 3 * 6 = 18 3 * 7 = 21 3 * 8 = 24 3 * 9 = 27 4 * 1 = 4 4 * 2 = 8 4 * 3 = 12 4 * 4 = 16 4 * 5 = 20 4 * 6 = 24 4 * 7 = 28 4 * 8 = 32 4 * 9 = 36 5 * 1 = 5 5 * 2 = 10 5 * 3 = 15 5 * 4 = 20 5 * 5 = 25 5 * 6 = 30 5 * 7 = 35 5 * 8 = 40 5 * 9 = 45
Решение:
n = int(input()) for i in range(1, n + 1): for j in range(1, 10): print(i, '*', j, '=', i * j) print()
Задание 9
Напишите программу, которая получает на вход нечетное положительное число n , и выводит треугольник, указывающий вправо.
Пример ввода:
11
Вывод:
* ** *** **** ***** ****** ***** **** *** ** *
Решение:
n = int(input()) for i in range(1, n // 2 + 2): print('*' * i, sep='n') for i in range(n // 2, 0, -1): print('*' * i)
Задание 10
Напишите программу, которая:
получает на вход x и y координаты n точек;
подсчитывает количество точек в каждой из координатных четвертей.
Примечание: к четвертям не относят точки, лежащие непосредственно на координатных осях X и Y .
Пример ввода:
8 -4 1 3 6 7 -9 -1 -10 15 5 -12 15 11 17 -10 1
Вывод:
Первая четверть: 3 Вторая четверть: 3 Третья четверть: 1 Четвертая четверть: 1
Решение:
q_1, q_2, q_3, q_4 = 0, 0, 0, 0 for _ in range(int(input())): x, y = [int(i) for i in input().split()] if int(x) > 0 and int(y) > 0: q_1 += 1 elif int(x) < 0 and int(y) > 0: q_2 += 1 elif int(x) < 0 and int(y) < 0: q_3 += 1 elif int(x) > 0 and int(y) < 0: q_4 += 1 print(f'Первая четверть: {q_1}', f'Вторая четверть: {q_2}', f'Третья четверть: {q_3}', f'Четвертая четверть: {q_4}', sep='n')
Подведем итоги
Цикл for универсален – его можно использовать для ввода, обработки и вывода данных. Простые циклы удобнее заменять генераторами и списковыми включениями, но сложные лучше использовать в обычном, развернутом виде – это упрощает отладку и чтение кода.
В следующей статье будем изучать особенности цикла while .
Содержание самоучителя
Особенности, сферы применения, установка, онлайн IDE
Все, что нужно для изучения Python с нуля – книги, сайты, каналы и курсы
Типы данных: преобразование и базовые операции
Методы работы со строками
Методы работы со списками и списковыми включениями
Методы работы со словарями и генераторами словарей
Методы работы с кортежами
Методы работы со множествами
Особенности цикла for
*** Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека питониста» Интересно, перейти к каналу