Лутц М. - Изучаем Python (1077325), страница 73
Текст из файла (страница 73)
е., если в цикле был выполнен обход всех элементов последовательности). Инструкции Ьгеа)< и сопС1пце, представленные выше, в циклах (ог работают точно так же, как и в циклах иЬ11е. Полная форма цикла Сог имеет следующий вид< № Викод из цикла, кинул блок е1зе № Переход в начало цикла Придется держать в уме: имитация циклов )д№Ы!е языка С В разделе главы 11, где рассматривались инструкции выражений, утверждалось, что язык РуСЬоп не предусматривает возможность выполнять присваивание там, где ожидается выражение. Это означает, что следующий, широко используемый шаблон программирования языка С неприменим в языке Рубьоп: ицс!е ((х = пехС( )) (= МЬ(1) (...
обработка и... ) Операции присваивания в языке С возвращают присвоенное значение, но в лзыке РуСЬоп присваиванне — это всего лишь инструкция, а не выражение. Благодаря этому ликвидируется обширный класс ошибок, свойственных языку С (в нзыке Ру()соп невозможно по ошибке оставить знак = там, где подразумевается ==). Но в случае необходимости в циклах ицс!е языка Ру()соп подобное поведение можно реализовать как минимум тремя способами, без встраивания инструкции присваивания в условное выражение.
Операцию присваивания можно переместить в тело цикла вместе с инструкцией Ьгеа(и гог <сагзес> сп <оь)есс>: <всасеэепсз> ст <Сеа(>; Ьгеак сг <сеас>: сопсспце е1зе: <зсасееепсз> № Связивает злеиенти объекта с переиенной цикла № Если не била вызвана инструкция 'Огеая' 339 Циклы (ог кю!е Тгое: х = пех(() 1( ПОТ Х: ЬгЕах обработка к...
или вместе с инструкцией 11: х=) аы1е х. х = пех1() тг х: ... обработка х. или вынести первое присваивание за пределы цикла: х = пех1() хПТ1Е х; обработка х х = пехт() Из этих трех вариантов первый, как могут полагать некоторые,— наименее структурированный, но он же представляется наиболее простым и наиболее часто используемым. (Простейший цикл тот в языке Ру1Ьоп также может заменить некоторые циклы языка С.) Примеры Рассмотрим несколько интерактивных циклов тот, чтобы вы могли увидеть, как они используются на практике. Типичные варианты использования Как упоминалось ранее, цикл тот может выполнять обход элементов в любых объектах последовательностей.
В нашем первом примере, например, мы поочередно, слева направо, присвоим переменной х каждый из трех элементов списка и выведем каждый из них с помощью инструкции рг(п1. Внутри инструкции рг(п1 (в теле цикла), имя х ссылается на текущий элемент списка: »> тот х 1п Гараа", "еаза", ''Паа" 3: рг1пт х, ераа еоое паэ Как отмечалось в главе 11, завершающая запятая в инструкции рг)пг подавляет вывод символа конца строки, в результате все элементы выводятся в одной строке. Глава 13.
Циклы ууЫе и [ог »> вца = 0 »> Гог х 1п [1, 2, 3, 4].' зца = зца + х »> зоа 10 »> ргоо = 1 »> Гог 11еа 1п (1, 2, 3, 4]: ргоо ° = 11еа »> ргоо 24 Другие типы данных Цикл 16г, будучи универсальным инструментом, может применяться к любым последовательностям. Например, цикл Тот может применять- ся к строкам и кортежам: »> 8 = "1цвэег)асх" »> Т = ("апо", "1'а", "оаау") »> Гог х тп 8: рг1пг х, в Обход строки 1 ц а Ь е г 1 а с К в Обход элементов кортеиа »> Гог х ьп Т: рг1п1 х, апб 1'а охау Фактически, как будет показано чуть ниже, циклы (ог могут приме- няться даже к объектам, которые вообще не являются последователь- ностями! Присваивание кортежа в цикле Фог Если выполнить обход последовательности кортежей, переменная цикла сама фактически будет кортежем.
Это лишь еще один случай операции присваивания кортежа. Не забывайте, что инструкция цик- ла Гог присваивает элементы объекта последовательности переменной цикла, а операция присваивания везде выполняется одинаково: »> Т = [(1, 2), (3, 4), (б, 6)] »> гог (а, ь) 1п т; в Операция присваивания кортеив в действии рг1пг а, Ь 1 2 3 4 5 б В следующих двух примерах вычисляется сумма и произведение всех элементов в списке. В этой главе и далее в книге мы познакомимся с инструментами, которые применяют такие операции, как + и *, к элементам списка автоматически, но обычно для этого используется цикл гог: 341 Цикпы 1ог ~десь первый проход цикла действует сходно инструкц (з Ь) = (1 тоРой пРохоД вЂ” инстРУкдии (а, Ь) = (3, 4) и т.
д. Это не какой то о бый случай — синтаксически после слова 1ог выполняется присваива- ние переменной цикла любого вида. Вложенные циклы Фог »> стева = ["ааа", 111, (4, 5), 2.01) »> Сев!в = [(4, 5), 3, 14) »> »> 1ог Кву !п севсв.' гог сСва !п стева: сг !!ЕЕ == Кеу: рг!пС Кву, юеав 1оопе" ЬгеаК № Множество обьектов № Ключи, которве требуется отжскать № Для всех ключей № Для всех злеиентов № Проверит~ совпадение есве; ргспС Кеу, "поС гоопю " (4 5) нав 1оьпб 3 14 пот 1оопб' Поскольку вложенная инструкция !1 вызывает инструкцию ЬгеаК, когда совпадение обнаружено, то можно утверждать, что блок е!зе будет выполняться только в случае, когда поиск завершится неудачей.
Обратите внимание на вложение инструкций. Если запустить этот фрагмент, одновременно будут выполняться два цикла: внешний цикл будет выполнять обход списка ключей, а внутренний будет выполнять обход списка элементов в поисках каждого ключа. Уровень вложенности блока е) зе имеет большое значение — он находится на уровне строки заголовка внутреннего цикла 1ог, поэтому он соответствует внутреннему циклу (не инструкции 11 и не внешнему циклу 1о г). Примечательно, что этот пример можно упростить, если использовать оператор !п для проверки вхождения ключа. Поскольку оператор !и неявно выполняет обход списка в поисках совпадения, он заменяет собой внутренний цикл: № Для всех клюющей № Позволить интерпретатору отнскать совпадение 1оопб »> 1ог Кеу сп Сев!в.
11 Кеу сп !Свае: ргспС Кеу, 5еав е!ве: рг!пС Кеу, "поС 1оопщ (4, 5) наз 1оопб 3. 14 пот 1оопб' Теперь рассмотрим нечто более сложное. Следующий пример иллюстрирует использование блока е)зе в цикле 1ог и вложенные инструкции. Имея список объектов (!сева) и список ключей (сев!э), этот фрагмент пытается отыскать каждый ключ в списке объектов и сообщает о результатах поиска: Глава 13.
Циклы ьу)1це и (ог 342 Вообще, ради компактности кода и скорости вычислений всегда правильнее будет переложить на плечи интерпретатора как можно больше работы, как это сделано в данном примере. Следующий пример с помощью цикла рог решает типичную задачу обработки данных — выборка одинаковых элементов из двух последовательностей [из строк). Это достаточно простая задача поиска пересечения двух множеств. После того как цикл рог выполнится, переменная гев будет ссылаться на список, содержащий все одинаковые элементы, обнаруженные в зес1 и вес2: »> гвв ['з', 'а', 'а'] К сожалению, этот фрагмент работает только с двумя определенными переменными: вес) и вес2.
Было бы замечательно, если бы этот цикл можно было привести к более универсальному виду, тогда его можно было бы использовать многократно. Эта простая идея ведет нас к функциям, теме следующей части книги. Итераторы: первое знакОмство В предыдущем разделе упоминалось, что цикл Гсг может работать с по- следовательностями любого типа в языке Ру$]>оп, включая списки, кортежи и строки, например: »> рог х 1п [1, 2, 3, 4]: рг1п1 х * 2, 1 4 9 16 »> Гог х 1п (1, 2, 3, 4): рг1п1 х ° 3, 1 8 27 64 »> рог х 1п 'враз': рг1пт х * 2, зв рр аа аа Фактически цикл [ог имеет еще более универсальную природу, чем было показано, — он способен работать с любыми объектами, поддерживающими возможность выполнения итераций. На самом деле это верно для всех средств выполнения итераций, которые выполняют сканирование объектов слева направо, включая циклы Гог, генераторы списков, оператор 1п проверки на вхождение и встроенную функцию аар.
»> ввв1 = "враз" »> вее2 "вова" >» »> гез = [] »> Гог х 1п веа1: 11 х 1п вео2: гвз.аррепо(х) а Изначально список пуст а Выполнить обход первой последовательности р Общий зленент? О )]сбавить в конец результата 343 Итераторы: первое знакомство Придется держать в уме: сканирование файлов Вообще циклы удобно использовать везде, где необходимо повторно выполнять некоторые действия или многократно обрабатывать данные. Файлы содержат множество символов и строк, поэтому они могут рассматриваться как один из типичных объектов применения циклов. Чтобы просто загрузить содержимое файла в строку одной инструкцией, достаточно вызвать метод геаб: тз1е = орел('тевт.тхт', 'г') ргбпт (11е.геаб() Но для загрузки файла по частям обычно используется либо цикл мпт1е, завершающийся инструкцией Ьгеак по достижении конца файла, либо цикл Тог. Чтобы выполнить посимвольное чтение, достаточно любого из следующих фрагментов: тт)е = преп('тевт тхт') ип!1е Тгсе спаг = 111е.геаб(1) 1г пот спаг; ьгеак рг(пт спаг.
№ Читать ло одному символу тот соаг 1п орел('тевт.тхт').геаб(): рг1пт сьаг Здесь цикл тот выполняет обработку каждого отдельного симво- ла, но загрузка содержимого файла в память производится одно- кратно. Чтение строками или блоками с помощью цикла мпт1е можно реализовать следующим образом: тт1е = орел('тевт.тхс') мы1е Тгие; 1зпе = (11е.геаб1(пе() зт пот 1тпе: ьгеак рг1пт 1тпе, № Читать строку аа строкой гт!е = орел('теат.тхт', 'гь') мот1е Тгое: спопх = тт1е геаб(10) 11 пот сьопх.