Перевод публикуется с сокращениями, автор оригинальной статьи David
Amos.
Выявление ошибок называется
дебаггингом, а дебаггер – помогающий понять причину их появления инструмент. Умение находить
и исправлять ошибки в коде – важный навык в работе программиста, не
пренебрегайте им.
IDLE (Integrated Development and Learning Environment) – кроссплатформенная интегрированная среда разработки и обучения для Python, созданная Гвидо ван Россумом.
Используйте окно управления отладкой
Основным интерфейсом отладки в IDLE является специальное окно управления (Debug Control window). Открыть его
можно, выбрав в меню интерактивного окна пункт Debug→Debugger.
Примечание: если отладка отсутствует в строке меню, убедитесь, что интерактивное окно находится
в фокусе.
Всякий раз, когда окно отладки
открыто, интерактивное окно отображает [DEBUG ON].
Обзор окна управления отладкой
Чтобы увидеть работу отладчика, напишем простую
программу без ошибок. Введите в редактор следующий код:
for i in range(1, 4):
j = i * 2
print(f"i is {i} and j is {j}")
Сохраните все, откройте окно отладки и нажмите клавишу F5 –
выполнение не завершилось.
Окно отладки будет выглядеть следующим образом:
Обратите внимание, что панель в верхней части окна содержит сообщение:
> '__main__'.<module>(), line 1: for i in range(1, 4):
Расшифруем: код for i in range(1, 4):
еще не запущен, а '__main__'.module()
сообщает, что в данный момент мы находимся в
основном разделе программы, а не в определении функции.
Ниже панели стека находится панель Locals, в которой
перечислены непонятные вещи: __annotations__, __builtins__, __doc__ и т. д. – это
внутренние системные переменные, которые пока можно игнорировать. По мере
выполнения программы переменные, объявленные в коде и отображаемые в этом окне,
помогут в отслеживании их значений.
В левом верхнем углу окна расположены пять кнопок:
Go, Step, Over, Out и Quit – они управляют перемещением отладчика по коду.
В следующих разделах вы узнаете, что делает каждая из
этих кнопок.
Кнопка Step
Нажмите Step и окно отладки будет выглядеть
следующим образом:
Обратите внимание на два отличия. Во-первых, сообщение на
панели стека изменилось:
> '__main__'.<module>(), line 2: j = i * 2:
На этом этапе выполняется line 1 и отладчик останавливается перед
выполнением line 2.
Во-вторых – новая переменная i со значением 1 на панели Locals. Цикл for в line 1
создал переменную и присвоил ей это значение.
Продолжайте нажимать кнопку Step, чтобы пройтись по коду
строка за строкой, и наблюдайте, что происходит в окне отладчика. Когда
доберетесь до строки print(f"i is {i} and j is {j}")
, сможете увидеть
вывод, отображаемый в интерактивном окне по одному фрагменту за раз.
Здесь важно, что можно отслеживать растущие значения i и j по
мере прохождения цикла for. Это полезная фича поиска источника ошибок в коде.
Знание значения каждой переменной в каждой строке кода может помочь точно
определить проблемную зону.
Точки останова и кнопка Go
Часто вам известно, что ошибка должна всплыть в определенном куске
кода, но неизвестно, где именно. Чтобы не нажимать кнопку Step весь
день, установите точку останова, которая скажет отладчику запускать весь код,
пока он ее не достигнет.
Точки останова сообщают отладчику, когда следует
приостановить выполнение кода, чтобы вы могли взглянуть на текущее состояние
программы.
Чтобы установить точку останова, щелкните правой кнопкой мыши
(Ctrl для Mac) по строке кода, на которой хотите сделать паузу, и выберите
пункт Set Breakpoint – IDLE выделит линию желтым. Чтобы удалить ее, выберите Clear
Breakpoint.
Установите точку останова в строке с оператором print(). Окно
редактора должно выглядеть так:
Сохраните и запустите. Как и раньше, панель стека указывает, что отладчик запущен и ожидает выполнения line 1. Нажмите
кнопку Go и посмотрите, что произойдет:
Теперь на панели стека информация о выполнении line 3:
> '__main__'.<module>(), line 3: print(f"i is {i} and j is {j}")
На панели Locals мы видим, что переменные i и j имеют значения 1
и 2 соответственно. Нажмем кнопку Go и попросим отладчик запускать код до точки
останова или до конца программы. Снова нажмите Go – окно отладки теперь выглядит так:
На панели стека отображается то же сообщение, что и раньше –
отладчик ожидает выполнения line 3. Однако значения переменных i и j теперь
равны 2 и 4. Интерактивное окно также отображает выходные данные после первого
запуска строки с помощью функции print() через цикл.
Нажмите кнопку в третий раз. Теперь i и j равны 3 и 6. Если
нажать Go еще раз, программа завершит работу.
Over и Out
Кнопка Over работает, как сочетание Step и Go – она
перешагивает через функцию или цикл. Другими словами, если вы собираетесь попасть
в функцию с помощью отладчика, можно и не запускать код этой функции – кнопка
Over приведет непосредственно к результату ее выполнения.
Аналогично если вы уже находитесь внутри функции или цикла –
кнопка Out выполняет оставшийся код внутри тела функции или цикла, а затем
останавливается.
В следующем разделе мы изучим некоторые ошибки и узнаем, как
их исправить с помощью IDLE.
Борьба с багами
Взглянем на «глючную» программу.
Следующий код определяет функцию add_underscores(), принимающую
в качестве аргумента строковый объект и возвращающую новую строку – копию слова с каждым символом, окруженным подчеркиванием. Например,
add_underscores("python")
вернет «_p_y_t_h_o_n_»
.
Вот неработающий код:
def add_underscores(word):
new_word = "_"
for i in range(len(word)):
new_word = word[i] + "_"
return new_word
phrase = "hello"
print(add_underscores(phrase))
Введите этот код в редактор, сохраните и нажмите F5.
Ожидаемый результат – _h_e_l_l_o_, но вместо этого выведется o_.
Если вы нашли, в чем проблема, не исправляйте ее. Наша цель – научиться
использовать для этого IDLE.
Рассмотрим 4 этапа поиска бага:
- предположите, где может быть ошибка;
- установите точку останова и проверьте код по строке за раз;
- определите строку и внесите изменения;
- повторяйте шаги 1-3, пока код не заработает.
Шаг 1: Предположение
Сначала вы не сможете точно определить местонахождение ошибки,
но обычно проще логически представить, в какой раздел кода смотреть.
Обратите внимание, что программа разделена на два раздела:
определение функции add_underscores() и основной блок, определяющий переменную
со значением «hello» и выводящий результат.
Посмотрим на основной раздел:
phrase = "hello"
print(add_underscores(phrase))
Очевидно, что здесь все хорошо и проблема должна быть в
определении функции:
def add_underscores(word):
new_word = "_"
for i in range(len(word)):
new_word = word[i] + "_"
return new_word
Первая строка создает переменную new_word со значением «_». Промах,
проблема находится где-то в теле цикла for.
Шаг 2: точка останова
Определив, где может быть ошибка, установите точку
останова в начале цикла for, чтобы проследить за происходящим внутри кода:
Запустим. Выполнение останавливается на строке с определением
функции.
Нажмите кнопку Go, чтобы выполнить код до точки останова:
Код останавливается перед циклом for в функции
add_underscores(). Обратите внимание, что на панели Locals отображаются две
локальные переменные – word со значением «hello», и new_word со значением «_»,
Нажмите кнопку Step, чтобы войти в цикл for. Окно отладки
изменится, и новая переменная i со значением 0 отобразится на панели Locals:
Переменная i – это счетчик для цикла for, который можно
использовать, чтобы отслеживать активную на данный момент итерацию.
Нажмите кнопку Step еще раз и посмотрите на панель Locals –
переменная new_word приняла значение «h_»:
Это неправильно т. к. сначала в new_word было значение «_», на
второй итерации цикла for в ней должно быть «_h_». Если нажать Step еще
несколько раз, то увидим, что в new_word попадает значение e_, затем l_ и так
далее.
Шаг 3: Определение ошибки и исправление
Как мы уже выяснили – на каждой итерации цикла new_word
перезаписывается следующим символом в строке «hello» и подчеркиванием.
Поскольку внутри цикла есть только одна строка кода, проблема должна быть именно
там:
new_word = word[i] + "_"
Код указывает Python получить следующий символ word,
прикрепить подчеркивание и назначить новую строку переменной new_word. Это
именно то неверное поведение, которое мы наблюдали.
Чтобы все починить, нужно объединить word[i] + "_"
с существующим значением new_word. Нажмите кнопку Quit в окне отладки, но не
закрывайте его. Откройте окно редактора и измените строку внутри цикла for на
следующую:
new_word = new_word + word[i] + "_"
Примечание: Если бы вы закрыли
отладчик, не нажав кнопку Quit, при повторном открытии окна отладки могла
появиться ошибка:
You can only toggle the debugger when
idle
Всегда нажимайте кнопку Go или Quit, когда заканчиваете отладку,
иначе могут возникнуть проблемы с ее повторным запуском.
Шаг 4: повторение шагов 1-3, пока ошибка не исчезнет
Сохраните изменения в программе и запустите ее снова. В окне
отладки нажмите кнопку Go, чтобы выполнить код до точки останова. Понажимайте
Step несколько раз и смотрите, что происходит с переменной new_word на каждой
итерации – все работает, как положено. Иногда необходимо повторять этот процесс
несколько раз, прежде чем исправится ошибка.
Альтернативные способы поиска ошибок
Использование отладчика может быть сложным и трудоемким, но
это самый надежный способ найти ошибки в коде. Однако отладчики не всегда есть в наличии. В подобных ситуациях можно использовать print debugging для поиска
ошибок в коде. PD задействует функцию print() для отображения в консоли текста, указывающего место выполнения программы и состояние
переменных.
Например, вместо отладки предыдущего примера можно добавить
следующую строку в конец цикла for:
print(f"i = {i}; new_word = {new_word}")
Измененный код будет выглядеть следующим образом:
def add_underscores(word):
new_word = "_"
for i in range(len(word)):
new_word = word[i] + "_"
print(f"i = {i}; new_word = {new_word}")
return new_word
phrase = "hello"
print(add_underscores(phrase))
Вывод должен выглядеть так:
i = 0; new_word = h_
i = 1; new_word = e_
i = 2; new_word = l_
i = 3; new_word = l_
i = 4; new_word = o_
o_
PD работает, но имеет
несколько недостатков по сравнению с отладкой дебаггером. Вы должны запускать
всю программу каждый раз, когда хотите проверить значения переменных, а также помнить про удаление вызовов функций print().
Один из способов улучшить наш цикл – перебирать символы в
word:
def add_underscores(word):
new_word = "_"
for letter in word:
new_word = new_word + letter + "_"
return new_word
Заключение
Теперь вы знаете все об отладке с помощью DLE.
Вы можете использовать этот принцип с
различными дебагерами.
В статье мы разобрали следующие темы:
- использование окна управления отладкой;
- установку точки останова для глубокого понимания работы кода;
- применение кнопок Step, Go, Over и Out;
- четырехэтапный процессом выявления и удаления ошибок.
Не останавливайтесь в обучении и практикуйте дебаггинг – это
весело!
Дополнительные материалы:
- ТОП-10 книг по Python: эффективно, емко, доходчиво
- Парсинг сайтов на Python: подробный видеокурс и программный код
- Python + Visual Studio Code = успешная разработка
- 29 Python-проектов, оказавших огромное влияние на разработку
- 15 вопросов по Python: как джуниору пройти собеседование
How I can find errors (Error1, Error2 , Error 3) from a file using for
loop.
A file contains three types of errors (strings
) from 4
different machines. Any machine can have any number of errors. whiptail
is used to create a pop-up window
whenver an error is found.
#!/bin/sh
if grep -R "Error1 in Machine 1" /home/new/Report.txt
then
echo "Error1 found in Machine 1"
whiptail --title "Report Error" --msgbox "Error 1 in Machine 1" 8 78
else
echo "No Error found"
fi
if grep -R "Error2 in Machine 1" /home/new/Report.txt
then
echo "Error2 found in Machine 1"
whiptail --title "Report Error" --msgbox "Error 2 in Machine 1" 8 78
else
echo "No Error found"
fi
if grep -R "Error2 in Machine 2" /home/new/Report.txt
then
echo "Error2 found in Machine 2"
whiptail --title "Report Error" --msgbox "Error 2 in Machine 2" 8 78
else
echo "No Error found"
fi
if grep -R "Error3 in Machine 3" /home/new/Report.txt
then
echo "Error3 found in Machine 3"
whiptail --title "Report Error" --msgbox "Error 3 in Machine 3" 8 78
else
echo "No Error found"
fi
asked Nov 26, 2021 at 15:47
1
#!/bin/bash
grep 'Error[1-3] in Machine [1-4]' /home/new/Report.txt |
while IFS= read -r errmsg
do
whiptail --title "Report Error" --msgbox "$errmsg" 8 78
done
The script doesn’t put the «No error found» message (no news is good news), but otherwise should work.
answered Nov 26, 2021 at 16:19
M. Nejat AydinM. Nejat Aydin
9,5661 gold badge6 silver badges17 bronze badges
1
If you have 3 errors and 4 machines you can use nested loops to handle all 12 combinations:
for ((e = 1; e <= 3; e++)); do
for ((m = 1; m <= 4; m++)); do
message="Error$e in Machine $m"
if grep -qF "$message" /home/new/Report.txt; then
echo "$message"
whiptail --title "Report Error" --msgbox "$message" 8 78
else
echo "No Error found"
fi
done
done
The grep
options q
(quiet) and F
are used to not print anything and to interpret the pattern as a fixed string, not a regular expression.
answered Nov 26, 2021 at 16:00
Renaud PacaletRenaud Pacalet
24k3 gold badges34 silver badges51 bronze badges
6
Pass grep
(1) one time and save the output, then do the rest.
#!/usr/bin/env bash
mapfile -t error_message < <(grep 'Error[[:digit:]] in Machine [[:digit:]]' /home/new/Report.txt)
((${#error_message[*]})) || { printf >&2 'No error message foundn'; exit; }
for message in "${error_message[@]}"; do
printf '%sn' "$message"
whiptail --title "Report Error" --msgbox "$message" 8 78
done
answered Nov 26, 2021 at 16:11
JetchiselJetchisel
7,3582 gold badges19 silver badges18 bronze badges
Нам в школе задали задачу, я решал как сказала учительница, но программа так не работает, пытался переделать по своему, получилось только в порядке возрастания. Вот задача:
По данному натуральному n ≤ 9 выведите возрастающую лесенку из n ступенек, последняя ступенька состоит из чисел от i до 1 через пробел.
n=int(input('Введите число '))
for i in range(1, n+2):
for i in range(i, 1):
print(i, end=' ')
print('n')
7
7 6
7 6 5
7 6 5 4
7 6 5 4 3
7 6 5 4 3 2
7 6 5 4 3 2 1
должен быть такой результат
задан 26 апр 2021 в 11:55
WaP1WaP1
431 серебряный знак5 бронзовых знаков
1
Надо просто тщательно всё посчитать откуда и докуда перечислять. И не забыть шаг указать в range
для цикла, у которого шаг отличается от стандартного шага 1:
n=int(input('Введите число '))
for i in range(1, n+1):
for j in range(n, n-i, -1):
print(j, end=' ')
print('n')
Вывод:
Введите число 7
7
7 6
7 6 5
7 6 5 4
7 6 5 4 3
7 6 5 4 3 2
7 6 5 4 3 2 1
ответ дан 26 апр 2021 в 12:14
CrazyElfCrazyElf
65.5k5 золотых знаков19 серебряных знаков50 бронзовых знаков
Подправил второй цикл:
n = 5
for i in range(1, n+2):
for j in range(i):
print(j, end=' ')
print()
Результат:
0
0 1
0 1 2
0 1 2 3
0 1 2 3 4
0 1 2 3 4 5
ответ дан 26 апр 2021 в 12:00
gil9redgil9red
76.4k6 золотых знаков51 серебряный знак117 бронзовых знаков
2
Цикл for/in
Еще одной важной инструкцией языка Python является цикл for/in, который можно смело назвать универсальным
итератором последовательностей, поскольку он позволяет выполнять обход элементов в любых объектах, поддерживающих возможность совершения итераций. При этом сюда относятся как встроенные объекты, например, строки,
списки или словари, так и объекты, создаваемые с помощью классов (о них чуть позже).
В общем виде для цикла for используется следующий синтаксис:
for <Переменная> in <Итерируемый объект>:
<Тело цикла>
else:
<Дополнительный блок инструкций>
В ходе выполнения цикла for интерпретатор один за другим присваивает переменной заголовка элементы итерируемого объекта и выполняет для них инструкции
тела цикла (см. пример №1). Если цикл нужно прервать, используется ключевое слово break, которое передает управление
инструкции, следующей сразу за циклом. Кроме того, в цикле for разрешается использовать необязательный блок else,
набор инструкций которого выполняется только после удачного завершения цикла (т.е. при отсутствии ошибки или прерывания за счет использования инструкции
break).
# Формируем список.
li = [2, 5, 9, 4]
# Задаем начальную сумму.
sum = 0
# Запускаем цикл по элементам списка.
for elem in li:
# Если сумма чисел меньше 8,
if sum < 8:
# наращиваем ее.
sum += elem
# Выводим для наглядности на экран.
print(sum)
# Иначе
else:
# выводим предупреждение и
print("Превышен лимит суммы эл-тов!")
# прерываем цикл.
break
# Если цикл не был прерван.
else:
# Выводим итоговое сообщение.
print("Сумма эл-тов равна:", sum)
# Выводим сообщение о завершении проверки.
print("Проверка списка завершена!")
2
7
16
Превышен лимит суммы эл-тов!
Проверка списка завершена!
Пример №1. Использование цикла for (часть 1).
В примере с помощью инструкции цикла for список проверяется на превышение лимита суммы его элементов. Для этого используется знакомая нам вложенная
условная инструкция if/else, которая и проверяет сумму на достижение лимита. Если в ходе очередной итерации цикла сумма не достигает указанного предела,
значение счетчика суммы sum увеличивается на значение переменной заголовка цикла elem, т.е.
sum += elem. После этого цикл переходит к следующей итерации и присваивает переменной elem значение следующего элемента
списка. И так до тех пор, пока не будет завершен обход всех элементов списка или не будет достигнут лимит суммы. Если лимит суммы достигнут не будет, сработает набор инструкций блока
else цикла, т.е. итоговая сумма будет выведена на экран. После этого будет выполнена инструкция, следующая за циклом. В случае достижения лимита,
сработает набор инструкций блока else условной инструкции if, т.е. будет выведено предупреждение, а цикл будет
прерван инструкцией break, которая передаст управление инструкции, опять же, следующей за циклом.
Обратите внимание, что в нашем примере были использованы два блока else: один принадлежит условной инструкции if,
а другой – инструкции цикла for/in. Отличить их легко по уровню отступов. Оба блока не являются обязательными в своих конструкциях, но в нашем
случае конструкция for/else, позволяет выводить итоговое сообщение не всегда, а только в случае успешного завершения цикла.
Также стоит помнить, что значение переменной заголовка цикла elem при каждой новой итерации обновляется, поэтому после завершения цикла в ней
будет храниться значение, присвоенное в ходе последней итерации.
Давайте рассмотрим еще несколько наглядных вариаций цикла for/in, чтобы увидеть, как он используется на практике (см. пример
№2).
# Выводим символы строки.
name = 'Григорий'
for s in name: print(s, end=' ')
print('', end='nn')
# Используем функцию range(a, b, step).
for n in range(1, len(name), 2):
# Выводим каждую вторую букву имени.
print(name[n], end=' ')
print('', end='nn')
# Выводим ключи и значения словаря.
d = {'one': 1, 'two': 2}
for key in d: print(key, '->', d[key])
print('', end='n')
# Используем распаковывание кортежей.
d = [(1, 2), (3, 4), (5, 6)]
for x, y in d: print(x + y, end=' ')
print('', end='nn')
# А здесь расширенный синтаксис распаковывания.
d = [(1, 2, 3), (4, 5, 6)]
for x, *y in d: print(x, y, end=' ')
Г р и г о р и й
р г р й
one -> 1
two -> 2
3 7 11
1 [2, 3] 4 [5, 6]
Пример №2. Использование цикла for (часть 2).
Как видим, инструкция цикла for в Python действительно имеет весьма простой синтаксис и с легкостью позволяет
совершать обход элементов в любых итерируемых объектах, в особенности внутри упорядоченных последовательностей вроде строк или списков, в которых обход осуществляется поочередно
в порядке возрастания индексов их элементов.
Цикл while
Инструкция цикла while представляет собой универсальный цикл общего назначения. Он служит для повторного выполнения кода, расположенного в его теле,
до тех пор, пока условие цикла остается истинным, т.е. имеет значение True. В общем случае синтаксис цикла while в
Python можно представить в следующем виде:
while <Условное выражение>:
<Тело цикла>
else:
<Дополнительный блок инструкций>
Работает цикл while следующим образом: каждый раз перед выполнением новой итерации, т.е. перед очередным выполнением блока инструкций в теле
цикла, происходит проверка его условия и, если результат будет иметь значение True, код в теле цикла выполняется; далее интерпретатор возвращается в начало цикла
и снова проверяет его условие, повторяя все процедуры заново до тех пор, пока условие цикла не вернет значение False; в этом случае интерпретатор прерывает
выполнение цикла и, пропустив блок инструкций в его теле, передает управление либо необязательному ключевому слову else, выполняя дополнительный блок
инструкций, либо инструкции, следующей за циклом. При этом следует иметь в виду, что набор инструкций блока else выполняется только тогда, когда выход из
цикла производится не инструкцией break (см. пример №3).
# Формируем список.
li = [2, 5, 9, 4]
# Задаем начальную сумму.
sum = 0
# Устанавливаем счетчик итераций.
k = 0
# Запускаем цикл по элементам списка.
while k < len(li):
# Если сумма чисел меньше 8,
if sum < 8:
# наращиваем ее.
sum += li[k]
# Отслеживаем показания счетчика и суммы.
print(k, ':', sum)
# Счетчик увеличиваем на 1.
k += 1
# Иначе
else:
# выводим предупреждение и
print("Превышен лимит суммы эл-тов!")
# прерываем цикл.
break
# Если цикл не был прерван.
else:
# Выводим итоговое сообщение.
print("Сумма эл-тов равна:", sum)
# Выводим сообщение о завершении проверки.
print("Проверка списка завершена!")
0 : 2
1 : 7
2 : 16
Превышен лимит суммы эл-тов!
Проверка списка завершена!
Пример №3. Использование цикла while (часть 1).
В нашем примере цикл совершил три итерации. На первых двух итерациях сумма элементов списка наращивалась, но не достигла допустимого предела. В результате этого цикл пошел на третий виток,
где сумма элементов все-таки превысила лимит. Это привело к тому, что цикл был прерван инструкцией break, а интерпретатор начал обрабатывать выражение
вызова функции print(), следующее за циклом. Если бы общая сумма всех элементов списка оказалась меньше допустимого лимита, цикл продолжил бы работу до
тех пор, пока переменная счетчика не стала бы равной четырем, а условие цикла не вернуло бы False. Далее интерпретатор пропустил бы блок инструкций тела
цикла и стал бы обрабатывать дополнительный набор инструкций его блока else. Попробуйте уменьшить значение элементов списка и убедитесь в этом.
Стоит заметить, что в языке Python отсутствует цикл do/while, имеющийся в других языках программирования. Однако его
можно имитировать, добавив в конец тела цикла условную инструкцию одновременно с инструкцией break (см. пример №4).
# Устанавливаем счетчик.
k = 1
# Запускаем бесконечный цикл.
while True:
# Выводим номер итерации.
print(k, end=' ')
# Счетчик увеличиваем на 1.
k += 1
# Имитируем условную часть цикла do/while.
if k > 5: break
1 2 3 4 5
Пример №4. Использование цикла while (часть 2).
Как видим, в данной имитации тело цикла при любом значении счетчика будет выполнено как минимум один раз, что является побочным эффектом проверки условия в конце цикла свойственного
реальной конструкции do/while.
Кстати, обратите внимание, что при использовании счетчиков в наших примерах мы инициализировали их вне циклов. Это нужно для того, чтобы при каждой новой итерации их значения не сбрасывались
циклом в первоначальное состояние.
Инструкции break и continue
Инструкции break и continue используются только внутри циклов и выполняют примерно те же функции, что и
в других языках программирования: break прерывает объемлющий цикл и передает управление следующей за циклом инструкции, а continue
прерывает только текущую итерацию и производит переход в начало цикла, т.е. в строку заголовка. При этом обе инструкции могут появляться в любом месте внутри тела цикла, но как правило,
их используют во вложенных в цикл условных инструкциях if, чтобы выполнить необходимое действие в ответ на некоторое условие (см. пример
№5).
# Устанавливаем счетчик.
k = 1
# Запускаем бесконечный цикл.
while True:
# Задаем условие прерывания цикла.
if k > 10:
# Прерываем цикл и идем дальше.
break
# Отсеиваем четные числа.
if k%2 == 0:
# Счетчик обязательно увеличиваем.
k += 1
# Пропускаем дальнейшие инструкции
# и возвращаемся в заголовок цикла.
continue
# Выводим нечетные числа на экран.
print(k, end=' ')
# Счетчик увеличиваем на 1.
k += 1
# Инструкция после цикла.
print('nВывод нечетных чисел окончен!n')
# Допустим, что имеется список чисел от 1 до 20.
li = list(range(1, 21))
# Запускаем цикл по элементам списка.
for k in li:
# Задаем условие прерывания цикла.
if k > 10:
# Прерываем цикл и идем дальше.
break
# Отсеиваем четные числа.
if k%2 == 0:
# Счетчик обязательно увеличиваем.
k += 1
# Пропускаем дальнейшие инструкции
# и возвращаемся в заголовок цикла.
continue
# Выводим нечетные числа на экран.
print(k, end=' ')
# Счетчик увеличиваем на 1.
k += 1
# Инструкция после цикла.
print('nВывод нечетных чисел окончен!')
1 3 5 7 9
Вывод нечетных чисел окончен!
1 3 5 7 9
Вывод нечетных чисел окончен!
Пример №5. Использование инструкций break и continue (часть 1).
Здесь хотелось бы обратить внимание на то, что все виды циклов в Python могут иметь другие вложенные циклы и условные инструкции, позволяя нужным образом
изменять дальнейший ход выполнения программы. Но дело в том, что каждая отдельная инструкция break или continue
относится только к одному ближайшему объемлющему циклу. Поэтому, например, выйти сразу из всех внешних циклов при помощи всего лишь одной инструкции break
расположенной в самом глубоком вложенном цикле не получится, нужно использовать инструкцию во всех циклах текущей иерархии (см. пример №6).
# Задаем стартовое значение счетчика.
y = 1
# Внешний цикл.
for x in range(1, 11):
# Умножение на 1 пропускаем.
if x == 1:
# Переходим в начало цикла for.
continue
# Внутренний цикл.
while True:
# Умножение на 1 пропускаем.
if y == 1:
# Увеличиваем счетчик на единицу.
y += 1
# Переходим в начало цикла while.
continue
# Выводим произведение чисел.
print('{} x {} = {}'.format(x, y, x*y))
# При достижении значения y == 5.
if y == 5:
# Переходим на новую строку.
print()
# Сбрасываем значение счетчика.
y = 2
# А внутренний цикл прерываем (внешний нет).
break
# Увеличиваем счетчик на единицу.
y += 1
# При достижении значения x == 5.
if x == 5:
# Прерываем и внешний цикл.
break
# Выводим сообщение о завершении циклов.
print('Таблица умножения от 2 до 5 распечатана!')
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10
3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15
4 x 2 = 8
4 x 3 = 12
4 x 4 = 16
4 x 5 = 20
5 x 2 = 10
5 x 3 = 15
5 x 4 = 20
5 x 5 = 25
Таблица умножения от 2 до 5 распечатана!
Пример №6. Использование инструкций break и continue (часть 2).
В Python отсутствует возможность использования конструкций вида break n или continue n,
где n указывало бы на количество прерываний внешних циклов. Вместо этого необходимо использовать собственные инструкции для каждого из
n циклов по отдельности.
Краткие итоги параграфа
-
Для обхода элементов в любых объектах, поддерживающих возможность совершения итераций, в Python предназначен цикл
for/in. В ходе выполнения этого цикла интерпретатор один за другим присваивает переменной заголовка элементы итерируемого объекта и выполняет для них
инструкции тела цикла. -
Для многократного повторного выполнения кода (не только обхода элементов) служит универсальный цикл общего назначения while, который выполняет блок
инструкций, расположенный в его теле, до тех пор, пока условие цикла остается истинным, т.е. имеет значение True. -
При необходимости в циклах for и while разрешается использовать необязательный блок
else, набор инструкций которого выполняется только после удачного завершения цикла (т.е. при отсутствии ошибки или прерывания за счет использования
инструкции break). - При использовании счетчиков следует инициализировать их вне циклов, чтобы при каждой новой итерации их значения не сбрасывались циклом в первоначальное состояние.
-
Для прерывания циклов в Python используется инструкция break, которая прерывает объемлющий цикл и передает управление
следующей за циклом инструкции. Если нужно прервать только текущую итерацию, необходимо использовать инструкцию continue, которая после прерывания
итерации производит переход в начало цикла, т.е. в строку заголовка. Обе инструкции могут появляться в любом месте внутри тела цикла, но как правило, их используют во вложенных
в цикл условных инструкциях if, чтобы выполнить необходимое действие в ответ на некоторое условие. -
Следует помнить, что в Python разрешается использовать многоуровневые вложенные циклы, однако при этом отсутствует возможность использования конструкций
вида break n или continue n, где n указывало бы на количество прерываний внешних
циклов. Вместо этого необходимо использовать собственные инструкции для каждого из n циклов по отдельности.
Вопросы и задания для самоконтроля
1. Для чего в программировании используются циклы? Какие виды циклов присутствуют в арсенале языка Python?
Показать решение.
Ответ. Циклы в программировании используются для организации многократного исполнения набора инструкций. В языке
Python циклы представлены конструкциями for/in и while: основным предназначением
цикла for является обход элементов итерируемого объекта, а while представляет собой универсальный цикл общего назначения.
Стоит заметить, что с помощью инструкции while можно сымитировать в том числе и счетный цикл for, однако программный код,
как хорошо видно из наших примеров выше, получится менее компактным и может выполняться медленнее.
2. Допустимо ли в Python использование вложенных друг в друга циклов?
Показать решение.
Ответ. В Python разрешается использовать как вложенные циклы, так и вложенные условные инструкции
if.
3. Обязательно ли использование блока else в циклах? При каких условиях он выполняется?
Показать решение.
Ответ. Блок инструкций оператора else в циклах не является обязательным, а его инструкции выполняются только
после удачного завершения цикла (т.е. при отсутствии ошибки или прерывания за счет использования оператора break).
4. В чем заключается основное отличие инструкции break от инструкции continue?
Показать решение.
Ответ. Инструкция break полностью прерывает объемлющий цикл и передает управление следующей за циклом
инструкции, в то время как инструкция continue прерывает только текущую итерацию и производит переход в начало цикла, т.е. в строку его заголовка.
5. Выведите все элементы списка [10, 20, 30] на экран сперва при помощи цикла for, а
затем и цикла while.
Показать решение.
# Сохраняем список в переменной.
li = [10, 20, 30]
# Организуем цикл по эл-там списка.
for elem in li:
# Выводим значения на экран.
print(elem, end=' ')
# Сделаем отступ для цикла while.
print()
# Инициализируем счетчик для цикла.
k = 0
# Узнаем требуемое количество итераций.
i = len(li)
# Организуем цикл по эл-там списка.
while k < i:
# Выводим значения на экран.
print(li[k], end=' ')
# Наращиваем значение счетчика.
k += 1
10 20 30
10 20 30
6. Дополнительные упражнения и задачи по теме расположены в разделе
«Циклы for и while»
нашего сборника задач и упражнений по языку программирования Python.
Быстрый переход к другим страницам
Public user contributions licensed under
cc-wiki license with attribution required