Математический анализ. 3е издание
Скачать 4.86 Mb.
|
continue Инструкция continue вызывает немедленный переход в начало цикла. Она иногда позволяет избежать использования вложенных инструк ций. В следующем примере инструкция используется для пропуска не четных чисел. Этот фрагмент выводит четные числа меньше 10 и боль ше или равные 0. Вспомним, что число 0 означает ложь, а оператор % вычисляет остаток от деления, поэтому данный цикл выводит числа в обратном порядке, пропуская значения, не кратные 2 (он выводит 8 6 4 2 0 ): x = 10 while x: x = x1 # Или, x = 1 if x % 2 != 0: continue # Нечетное? – пропустить вывод print x, Так как инструкция continue выполняет переход в начало цикла, нам не потребовалось вкладывать инструкцию print в инструкцию if – она будет задействована, только если инструкция continue не будет выпол нена. Если она напоминает вам инструкцию «goto», имеющуюся в дру гих языках, то это справедливо. В языке Python нет инструкции goto, но так как инструкция continue позволяет выполнять переходы внутри программы, большинство замечаний, касающихся удобочитаемости и простоты сопровождения, которые вы могли слышать в отношении инструкции goto, применимы и к инструкции continue. Не злоупотреб ляйте использованием этой инструкции, особенно когда вы только на чинаете работать с языком Python. Например, последний пример вы глядел бы понятнее, если бы инструкция print была вложена в инст рукцию if: x = 10 while x: x = x1 if x % 2 == 0: # Четное? вывести print x, break Инструкция break вызывает немедленный выход из цикла. Так как программный код, следующий в цикле за этой инструкцией, не вы break, continue, pass и else 335 полняется, если эта инструкция запущена, то ее также можно исполь зовать, чтобы избежать вложения. Например, ниже приводится про стой интерактивный цикл (вариант более крупного примера, рассмат ривавшегося в главе 10), где производится ввод данных с помощью функции raw_input и выход из цикла, если в ответ на запрос имени бу дет введена строка «stop»: >>> while 1: ... name = raw_input('Enter name:') ... if name == 'stop': break ... age = raw_input('Enter age: ') ... print 'Hello', name, '=>', int(age) ** 2 Enter name:mel Enter age: 40 Hello mel => 1600 Enter name:bob Enter age: 30 Hello bob => 900 Enter name:stop Обратите внимание, как в этом примере выполняется преобразование строки age в целое число с помощью функции int, перед тем как воз вести его во вторую степень. Как вы помните, это совершенно необхо димо, потому что функция raw_input возвращает ввод пользователя в виде строки. В главе 29 вы увидите, что функция raw_input также воз буждает исключение при получении символа конца файла (например, когда пользователь нажимает комбинацию клавиш CtrlZ или CtrlD). Если это может иметь влияние, оберните вызов функции инструкцией try else При объединении с частью else инструкция break часто позволяет из бавиться от необходимости сохранять флаг состояния поиска, как это делается в других языках программирования. Например, следующий фрагмент определяет, является ли положительное целое число y про стым числом, выполняя поиск делителей больше 1: x = y / 2 # Для значений y > 1 while x > 1: if y % x == 0: # Остаток print y, 'has factor', x break # Перешагнуть блок else x = x1 else: # Нормальное завершение цикла print y, 'is prime' Вместо того чтобы устанавливать флаг, который будет проверен по окон чании цикла, достаточно вставить инструкцию break в месте, где будет найден делитель. При такой реализации в блоке else цикла, который 336 Глава 13. Циклы while и for будет выполнен, только если инструкция break не была запущена, можно с уверенностью сказать, что число является простым. 1 Блок else цикла выполняется также в том случае, когда тело цикла ни разу не выполнялось, поскольку в этой ситуации инструкция break так же не выполняется. В циклах while это происходит, когда первая же проверка условия в заголовке дает ложное значение. Вследствие этого в предыдущем примере будет получено сообщение «is prime» (простое число), если изначально x меньше или равно 1 (т. е., когда y равно 2). Еще о блоке else в цикле Так как блок else в цикле является уникальной особенностью языка Python, он нередко становится источником недопонимания для тех, кто только начинает осваивать его. В общих чертах, блок else в циклах обеспечивает явный синтаксис представления распространенной си туации – эта программная структура позволяет обработать «другой» способ выхода из цикла, без необходимости устанавливать и прове рять флаги или условия. Предположим, например, что вы создаете цикл поиска некоторого зна чения в списке и после выхода из цикла вам необходимо узнать, было ли найдено значение. Эту задачу можно решить следующим способом: found = False while x and not found: if match(x[0]): # Искомое значение является первым? print 'Ni' found = True else: x = x[1:] # Вырезать первое значение и повторить if not found: print 'not found' Здесь мы инициализируем, устанавливаем и проверяем флаг, чтобы определить, увенчался поиск успехом или нет. Это вполне корректный программный код для языка Python, и он работает, однако это именно тот случай, когда можно использовать блок else в цикле. Ниже приво дится эквивалентный фрагмент: while x: # Выйти, когда x опустеет if match(x[0]): 1 Более или менее. Числа, меньшие 2, не считаются простыми в соответствии со строгим математическим определением. Если быть более точным, этот программный код также будет терпеть неудачу при отрицательных значе ниях и при использовании чисел с плавающей точкой, и в будущем утратит работоспособность изза грядущих изменений в поведении оператора /, ко торый будет выполнять операцию «истинного деления», как описано в гла ве 5. Если вы захотите поэкспериментировать с этим фрагментом, загляните в упражнения к четвертой части книги, где этот пример обернут в функцию. Циклы for 337 print 'Ni' break # Выход, в обход блока else x = x[1:] else: print 'Not found' # Этот блок отработает, только если строка x исчерпана Эта версия более компактна. Нам удалось избавиться от флага и заме нить инструкцию if за циклом на блок else (по вертикали находится на одной линии со словом while). Так как выход из цикла while по инст рукции break минует блок else, его можно рассматривать как более удобный способ обработки случая неудачного поиска. Некоторые из вас могли бы заметить, что в предыдущем примере блок else можно заменить проверкой строки x после выхода из цикла (напри мер, if not x:). Для данного примера это вполне возможно, но часть else обеспечивает явный синтаксис реализации этого шаблона программи рования (здесь – это более очевидный блок обработки ситуации неудач ного поиска), и кроме того, подобная проверка не всегда возможна. Часть else в циклах становится еще более полезной, когда используется в сочетании с инструкцией цикла for – темой следующего раздела, пото му что обход последовательностей выполняется неподконтрольно вам. Циклы for Цикл for является универсальным итератором последовательностей в языке Python: он может выполнять обход элементов в любых упоря доченных объектах последовательностей. Инструкция for способна ра ботать со строками, списками, кортежами, с другими встроенными объ ектами, поддерживающими возможность выполнения итераций, и с но выми объектами, которые создаются с помощью классов, как будет по казано позже. Общий формат Циклы for в языке Python начинаются со строки заголовка, где указы вается переменная для присваивания (или – цель), а также объект, об ход которого будет выполнен. Вслед за заголовком следует блок (обычно с отступами) инструкций, которые требуется выполнить: for 338 Глава 13. Циклы while и for Имя, используемое в качестве переменной цикла (возможно, новой), которое указывается в заголовке цикла for, обычно находится в облас ти видимости, где располагается сама инструкция for. О ней почти не чего сказать; хотя она может быть изменена в теле цикла, тем не менее, ей автоматически будет присвоен следующий элемент последователь ности, когда управление вернется в начало цикла. После выхода из цикла эта переменная обычно все еще ссылается на последний элемент последовательности, если цикл не был завершен инструкцией break. Инструкция for также поддерживает необязательную часть else, кото рая работает точно так же, как и в циклах while, – она выполняется, ес ли выход из цикла производится не инструкцией break (т. е., если в цик ле был выполнен обход всех элементов последовательности). Инструк ции break и continue, представленные выше, в циклах for работают точ но так же, как и в циклах while. Полная форма цикла for имеет следующий вид: for Циклы for 339 Примеры Рассмотрим несколько интерактивных циклов for, чтобы вы могли увидеть, как они используются на практике. Типичные варианты использования Как упоминалось ранее, цикл for может выполнять обход элементов в любых объектах последовательностей. В нашем первом примере, на пример, мы поочередно, слева направо, присвоим переменной x каж дый из трех элементов списка и выведем каждый из них с помощью инструкции print. Внутри инструкции print (в теле цикла), имя x ссы лается на текущий элемент списка: >>> for x in ["spam", "eggs", "ham"]: ... print x, spam eggs ham Как отмечалось в главе 11, завершающая запятая в инструкции print подавляет вывод символа конца строки, в результате все элементы вы водятся в одной строке. while True: x = next() if not x: break ...обработка x... или вместе с инструкцией if: x = 1 while x: x = next() if x: ...обработка x... или вынести первое присваивание за пределы цикла: x = next() while x: ...обработка x... x = next() Из этих трех вариантов первый, как могут полагать некоторые, – наименее структурированный, но он же представляется наибо лее простым и наиболее часто используемым. (Простейший цикл for в языке Python также может заменить некоторые циклы языка C.) 340 Глава 13. Циклы while и for В следующих двух примерах вычисляется сумма и произведение всех элементов в списке. В этой главе и далее в книге мы познакомимся с инструментами, которые применяют такие операции, как + и *, к элементам списка автоматически, но обычно для этого используется цикл for: >>> sum = 0 >>> for x in [1, 2, 3, 4]: ... sum = sum + x >>> sum 10 >>> prod = 1 >>> for item in [1, 2, 3, 4]: prod *= item >>> prod 24 Другие типы данных Цикл for, будучи универсальным инструментом, может применяться к любым последовательностям. Например, цикл for может применять ся к строкам и кортежам: >>> S = "lumberjack" >>> T = ("and", "I'm", "okay") >>> for x in S: print x, # Обход строки l u m b e r j a c k >>> for x in T: print x, # Обход элементов кортежа and I'm okay Фактически, как будет показано чуть ниже, циклы for могут приме няться даже к объектам, которые вообще не являются последователь ностями! Присваивание кортежа в цикле for Если выполнить обход последовательности кортежей, переменная цикла сама фактически будет кортежем. Это лишь еще один случай операции присваивания кортежа. Не забывайте, что инструкция цик ла for присваивает элементы объекта последовательности переменной цикла, а операция присваивания везде выполняется одинаково: >>> T = [(1, 2), (3, 4), (5, 6)] >>> for (a, b) in T: # Операция присваивания кортежа в действии ... print a, b 1 2 3 4 5 6 Циклы for 341 Здесь первый проход цикла действует сходно инструкции (a, b) = (1, 2), второй проход – инструкции (a, b) = (3, 4) и т. д. Это не какойто осо бый случай – синтаксически после слова for выполняется присваива ние переменной цикла любого вида. Вложенные циклы for Теперь рассмотрим нечто более сложное. Следующий пример иллюст рирует использование блока else в цикле for и вложенные инструк ции. Имея список объектов (items) и список ключей (tests), этот фраг мент пытается отыскать каждый ключ в списке объектов и сообщает о результатах поиска: >>> items = ["aaa", 111, (4, 5), 2.01] # Множество объектов >>> tests = [(4, 5), 3.14] # Ключи, которые требуется отыскать >>> >>> for key in tests: # Для всех ключей ... for item in items: # Для всех элементов ... if item == key: # Проверить совпадение ... print key, "was found" ... break ... else: ... print key, "not found!" (4, 5) was found 3.14 not found! Поскольку вложенная инструкция if вызывает инструкцию break, ко гда совпадение обнаружено, то можно утверждать, что блок else будет выполняться только в случае, когда поиск завершится неудачей. Об ратите внимание на вложение инструкций. Если запустить этот фраг мент, одновременно будут выполняться два цикла: внешний цикл бу дет выполнять обход списка ключей, а внутренний будет выполнять обход списка элементов в поисках каждого ключа. Уровень вложенно сти блока else имеет большое значение – он находится на уровне стро ки заголовка внутреннего цикла for, поэтому он соответствует внут реннему циклу (не инструкции if и не внешнему циклу for). Примечательно, что этот пример можно упростить, если использовать оператор in для проверки вхождения ключа. Поскольку оператор in неявно выполняет обход списка в поисках совпадения, он заменяет со бой внутренний цикл: >>> for key in tests: # Для всех ключей ... if key in items: # Позволить интерпретатору отыскать совпадение ... print key, "was found" ... else: ... print key, "not found!" (4, 5) was found 3.14 not found! 342 Глава 13. Циклы while и for Вообще, ради компактности кода и скорости вычислений всегда пра вильнее будет переложить на плечи интерпретатора как можно боль ше работы, как это сделано в данном примере. Следующий пример с помощью цикла for решает типичную задачу об работки данных – выборка одинаковых элементов из двух последова тельностей (из строк). Это достаточно простая задача поиска пересече ния двух множеств. После того как цикл for выполнится, переменная res будет ссылаться на список, содержащий все одинаковые элементы, обнаруженные в seq1 и seq2: >>> seq1 = "spam" >>> seq2 = "scam" >>> >>> res = [] # Изначально список пуст >>> for x in seq1: # Выполнить обход первой последовательности ... if x in seq2: # Общий элемент? ... res.append(x) # Добавить в конец результата >>> res ['s', 'a', 'm'] К сожалению, этот фрагмент работает только с двумя определенными переменными: seq1 и seq2. Было бы замечательно, если бы этот цикл можно было привести к более универсальному виду, тогда его можно было бы использовать многократно. Эта простая идея ведет нас к функ циям, теме следующей части книги. Итераторы: первое знакомство В предыдущем разделе упоминалось, что цикл for может работать с по следовательностями любого типа в языке Python, включая списки, кортежи и строки, например: >>> for x in [1, 2, 3, 4]: print x ** 2, 1 4 9 16 >>> for x in (1, 2, 3, 4): print x ** 3, 1 8 27 64 >>> for x in 'spam': print x * 2, ss pp aa mm Фактически цикл for имеет еще более универсальную природу, чем было показано, – он способен работать с любыми объектами, поддержи вающими возможность выполнения итераций. На самом деле это вер но для всех средств выполнения итераций, которые выполняют скани рование объектов слева направо, включая циклы for, генераторы спи сков, оператор in проверки на вхождение и встроенную функцию map. |