Лутц М. - Изучаем Python (1077325), страница 72
Текст из файла (страница 72)
Обратите внимание, что тело этого цикла иЬ11е находится в той же строке, что и заголовок, после двоеточия. Как и в случае с инструкцией 11, такой прием можно использовать только в случае, когда тело цикла образует несоставная инструкция. Этот пример вечно делает «ничто». Вероятно это самая бесполезная программа (если только вы не хотите погреться у своего ноутбука в холодный зимний день!), которая когда-либо была написана на языке Ру$)топ, и, тем не менее, я не смог придумать лучший пример применения инструкции разя. Далее мы увидим, где эта инструкция может использоваться с большим смыслом, например, для определения пустых Общий формат цикла С учетом инструкций ЬгеаК и соп1(пце цикл ио|1е в общем виде выглядит, как показано ниже: Глава 13. Циклы ЧЧЫ)е и )ог классов, реализующих объекты, которые ведут себя подобно структу- рам и записям в других языках.
Иногда инструкция разе используется как заполнитель, вместо того, «что будет написано позднее», и в каче- стве временного фиктивного тела функций: Оег гппс1(): рава № Настояний программнмй код будет добавлен позие бет Гппс2(). реев сопбпие Инструкция сопг)псе вызывает немедленный переход в начало цикла. Она иногда позволяет избежать использования вложенных инструкций. В следующем примере инструкция используется для пропуска нечетных чисел. Этот фрагмент выводит четные числа меньше 10 и больше или равные О. Вспомним, что число О означает ложь, а оператор 72 вычисляет остаток от деления, поэтому данный цикл выводит числа в обратном порядке, пропуская значения, не кратные 2 (он выводит 86420): к=10 ис71е х; х=х-1 77 х 7» 2 '= 0 соп17ппе ргтпт х.
№ Или, х -= 7 № Нечетное? - пропустить вывод х = 10 ию1е х; х = х-1 17 х)»2 ==0: ргтпт х, № Четное? -- вивести ЬгеаЕ Инструкция ЬгеаК вызывает немедленный выход из цикла. Так как программный код, следующий в цикле за этой инструкцией, не вы- Так как инструкция сопыппе выполняет переход в начало цикла, нам не потребовалось вкладывать инструкцию р гтп1 в инструкцию 7? — она будет задействована, только если инструкция соп11пое не будет выполнена. Если она напоминает вам инструкцию «яо10», имеющуюся в других языках, то это справедливо. В языке РуФ)уоп нет инструкции яо№хх, но так как инструкция сепг!псе позволяет выполнять переходы внутри программы, большинство замечаний, касающихся удобочитаемости и простоты сопровождения, которые вы могли слышать в отношении инструкции досо, применимы и к инструкции соп17 псе.
Не злоупотребляйте использованием этой инструкции, особенно когда вы только начинаете работать с языком РуС)7оп. Например, последний пример выглядел бы понятнее, если бы инструкция рг)пт была вложена в инструкцию 7?7 ЬгеаЕ, сопбпие, рава и ейе полняется, если эта инструкция запущена, то ее также можно использовать, чтобы избежать вложения. Например, ниже приводится простой интерактивный цикл (вариант более крупного примера, рассматривавшегося в главе 10), где производится ввод данных с помощью функции гаш тпрот и выход из цикла, если в ответ на запрос имени будет введена строка «втор»: »> ипт)в т; паев = гаи 1прот('Ептвг паав;') 1( паав == 'втор'; Ьгваа адв = гаи 1прот('Ептвг адв: ') рг1пт 'нв11о', паап, '=>', 1пт(адв) .
2 Обратите внимание, как в этом примере выполняется преобразование строки аде в целое число с помощью функции тпт, перед тем как возвести его во вторую степень. Как вы помните, это совершенно необходимо, потому что функция гаи тпрот возвращает ввод пользователя в виде строки. В главе 29 вы увидите, что функция гаи 1прот также возбуждает исключение при получении символа конца файла (например, когда пользователь нажимает комбинацию клавиш ЕтгЫ или Стг(-0). Если это может иметь влияние, оберните вызов функции инструкцией тгу. е!ве При объединении с частью е1бе инструкция Ьгеау часто позволяет избавиться от необходимости сохранять флаг состояния поиска, как это делается в других языках программирования.
Например, следующий фрагмент определяет, является ли положительное целое число у простым числом, выполняя поиск делителей больше 1: р Длл значений у > т х = у г' 2 иот1в х > 1; тт у % х == 0; ргтпт у, 'паа Гастог', Ьгвах х = х-1 в1ве: рмпт у, 'тв рг1ав' р Остаток х Ф Перешагнуть блок в)зв р Нориальнов завершение цикла Вместо того чтобы устанавливать флаг, который будет проверен по окончании цикла, достаточно вставить инструкцию Ьгеаи в месте, где будет найден делитель. При такой реализации в блоке е1ве цикла, который Ептвг Ептвг Не11о Ептег Ептег Нв11о Ептвг паап;ав1 адв: 40 ав1 => 1000 паав:ЬоЬ аде: 30 ЬоЬ => 900 паав:втор 33б Глава 13. Циклы игО~(е и (ог будет выполнен, только если инструкция ОгеаК не была запущена, можно с уверенностью сказать, что число является простым.' Блок е1ве цикла выполняется также в том случае, когда тело цикла ни разу не выполнялось, поскольку в этой ситуации инструкция Отвага так- же не выполняется.
В циклах илт1е это происходит, когда первая же проверка условия в заголовке дает ложное значение. Вследствие этого в предыдущем примере будет получено сообщение»1в ргппе» (простое число), если изначально х меньше или равно 1 (т. е., когда у равно 2). ЕЩЕ О бЛОКЕ Е1ВЕ В ЦИКЛЕ Так как блок в1ве в цикле является уникальной особенностью языка Ру1Ьоп, он нередко становится источником недопонимания для тех, кто только начинает осваивать его. В общих чертах, блок е1ве в циклах обеспечивает явный синтаксис представления распространенной ситуации — эта программная структура позволяет обработать «другой» способ выхода из цикла, без необходимости устанавливать и проверять флаги или условия.
Предположим, например, что вы создаете цикл поиска некоторого зна- чения в списке и после выхода из цикла вам необходимо узнать, было ли найдено значение. Эту задачу можно решить следующим способом: Гонов = Га1зе илг1е х апс пот Гонпс; тг загон(х(01). рг1пг 'Ит' Тонне = Тгне е1ае; х = х(1:1 ТГ пот Тонно; рыб 'пот (онпз' № Исковое значение является первыив № Вырезать первое значение и повторить ипт1е х; № Выдти, когда х опустеет тг эагсп(х(01); Более или менее. Числа, меньшие 2, не считаются простыми в соответствии со строгим математическим определением.
Если быть более точным, этот программный код также будет терпеть неудачу прн отрицательных значениях и при использовании чисел с плавающей точкой, и э будущем утратит работоспособность из-за грядущих изменений э поведении оператора /, который будет выполнять операцию»истинного деления», как описано э главе 5.
Если вы захотите поэкспериментировать с этим фрагментом, загляните в упражнения к четвертой части книги, где этот пример обернут в функцию. Здесь мы инициализируем, устанавливаем и проверяем флаг, чтобы определить, увенчался поиск успехом или нет. Это вполне корректный программный код для языка РуФЬоп, и он работает, однако это именно тот случай, когда можно использовать блок е1ве в цикле. Ниже приводится эквивалентный фрагмент: ззу [[икры [ог Рыпт а[ Ьгеак № Вьхол, в обход блока еаза х = х[1:1 е1ае. ргшт 'цо1 Гоцпо' № Этот блок отработает, тол~ко если строкз к исчерпана Эта версия более компактна.
Нам удалось избавиться от флага и заменить инструкцию уг за циклом на блок е1ее (по вертикали находится на одной линии со словом нЬ11е). как как выход из цикла тгЬ11е по инструкции Ьгеац минует блок е1ае, его можно рассматривать как более удобный способ обработки случая неудачного поиска. Некоторые из вас могли бы заметить, что в предыдущем примере блок е1эе можно заменить проверкой строки х после выхода из цикла (например, [т по[ х: ). Для данного примера это вполне возможно, но часть е1ае обеспечивает явный синтаксис реализации этого шаблона программирования (здесь — это более очевидный блок обработки ситуации неудачного поиска), и кроме того, подобная проверка не всегда возможна.
Часть е1ае в циклах становится еще более полезной, когда используется в сочетании с инструкцией цикла [от — темой следующего раздела, потому что обход последовательностей выполняется неподконтрольно вам. Циклы аког Цикл гсг является универсальным итератором последовательностей в языке РуФоп: он может выполнять обход элементов в любых упорядоченных объектах последовательностей. Инструкция гог способна работать со строками, списками, кортежами, с другими встроенными объектами, поддерживающими возможность выполнения итераций, и с новыми объектами, которые создаются с помощью классов, как будет показано позже. Общий формат Циклы [ог в языке РуФ)топ начинаются со строки заголовка, где указывается переменная для присваивания (или — цель), а также объект, обход которого будет выполнен.
Вслед за заголовком следует блок (обычно с отступами) инструкций, которые требуется выполнить: гог <тагое1> 1п <оь1ест>: № сввзцвает злеиентц обьекта с переиенной цикла <зта1еюемв> № Повторлююеесп тело цикла: использует переменную цикла е1ае. <зтатеюепш> № Если не попали на инструкцию 'Ьгезх Когда интерпретатор выполняет цикл гсг, он поочередно, один за другим, присваивает элементы объекта последовательности переменной цикла и выполняет тело цикла для каждого из них. Для обращения к текущему элементу последовательности в теле цикла обычно используется переменная цикла, как если бы это был курсор, шагающий от элемента к элементу.
Глаза )3. Циклы ууИе и (ог 338 Имя, используемое в качестве переменной цикла (возможно, новой), которое указывается в заголовке цикла Гог, обычно находится в области видимости, где располагается сама инструкция Гог. О ней почти нечего сказать; хотя она может быть изменена в теле цикла, тем не менее, ей автоматически будет присвоен следующий элемент последовательности, когда управление вернется в начало цикла. После выхода из цикла эта переменная обычно все еще ссылается на последний элемент последовательности, если цикл не был завершен инструкцией Ьгеац. Инструкция Гог также поддерживает необязательную часть е1ае, которая работает точно так же, как и в циклах иЬ11е, — она выполняется, если выход из цикла производится не инструкцией Ь г еаза (т.