Что покажет приведенный ниже фрагмент кода mystr да mystr mystr нет mystr mystr да print mystr
Перейти к содержимому

Что покажет приведенный ниже фрагмент кода mystr да mystr mystr нет mystr mystr да print mystr

  • автор:

Что покажет приведенный ниже фрагмент кода mystr да mystr mystr нет mystr mystr да print mystr

Все решения и ответы на модуль (урок) 6.3 из программы «Поколение Python: курс для начинающих».

Целью этого занятия будет научиться работать со строками и производить операции с ними.

Что покажет приведенный ниже фрагмент кода?

mystr = ‘да’
mystr = mystr + ‘нет’
mystr = mystr + ‘да’
print(mystr)

Ответ: данетда

Что покажет приведенный ниже фрагмент кода?

str1 = ‘1’
str2 = str1 + ‘2’ + str1
str3 = str2 + ‘3’ + str2
str4 = str3 + ‘4’ + str3
print(str4)

Ответ: 121312141213121

Что покажет приведенный ниже фрагмент кода?

mystr = ‘123’ * 3 + ‘456’ * 2 + ‘789’ * 1
print(mystr)

Ответ: 123123123456456789

Напишите программу, которая выводит текст:

«Python is a great language!», said Fred. «I don’t ever remember having this much fun before.»

What’s Your Name?

Напишите программу, которая считывает с клавиатуры две строки – имя и фамилию пользователя и выводит фразу:

«Hello [введенное имя] [введенная фамилия]! You just delved into Python».

Формат входных данных
На вход программе подаётся две строки (имя и фамилия), каждая на отдельной строке.

Формат выходных данных
Программа должна вывести текст в соответствии с условием задачи.

Примечание. Между firstname lastname вставьте пробел =)

Футбольная команда

Напишите программу, которая считывает с клавиатуры название футбольной команды и выводит фразу:

«Футбольная команда [введённая строка] имеет длину [длина введённой строки] символов».

Формат входных данных
На вход программе подаётся строка – название футбольной команды.

Формат выходных данных
Программа должна вывести текст в соответствии с условием задачи.

Три города

Даны названия трех городов. Напишите программу, которая определяет самое короткое и самое длинное название города.

Формат входных данных
На вход программе подаётся названия трех городов, каждое на отдельной строке.

Формат выходных данных
Программа должна вывести самое короткое и длинное название города, каждое на отдельной строке.

Примечание. Гарантируется, что длины названий всех трех городов различны.

Арифметические строки

Вводятся 3 строки в случайном порядке. Напишите программу, которая выясняет можно ли из длин этих строк построить возрастающую арифметическую прогрессию.

Формат входных данных
На вход программе подаются три строки, каждая на отдельной строке.

Формат выходных данных
Программа должна вывести строку «YES», если из длин введенных слов можно построить арифметическую прогрессию, «NO» в ином случае.

Какие значения может принимать строковая переменная s , чтобы в результате выполнения кода было выведено слово «YES»?

if s in ‘abc123abc’:
print(‘YES’)
else:
print(‘NO’)

  • s = ’23’
  • s = ‘123abc’
  • s = ‘3ab’
  • s = ‘a’
  • s = ‘1’

Цвет настроения синий

Напишите программу, которая считывает одну строку, после чего выводит «YES», если в введенной строке есть подстрока «синий» и «NO» в противном случае.

Формат входных данных
На вход программе подается одна строка.

Формат выходных данных
Программа должна вывести текст в соответствии с условием задачи.

Отдыхаем ли?

Напишите программу, которая считывает одну строку, после чего выводит «YES», если в введённой строке есть подстрока «суббота» или «воскресенье», и «NO» в противном случае.

Формат входных данных
На вход программе подается одна строка.

Формат выходных данных
Программа должна вывести текст в соответствии с условием задачи.

Корректный email

Будем считать email адрес корректным, если в нем есть символ собачки (@) и точки. Напишите программу проверяющую корректность email адреса.

Формат входных данных
На вход программе подаётся одна строка – email адрес.

Формат выходных данных
Программа должна вывести строку «YES», если email адрес является корректным и «NO» в ином случае.

Примечание. Наличие символов @ и . недостаточно для корректности email адреса, однако их отсутствие гарантировано влечёт за собой неверный email.

Перестановки рекурсии Python

У меня проблемы с попыткой сделать код перестановки с рекурсией. Это должно вернуть список обратно в использование со всеми возможными позициями для каждой буквы. так что к слову cat предполагается вернуться [‘cat’,’act’,atc,’cta’,’tca’,’tac’] . пока у меня есть это

Там есть шаги, но я не уверен, как их использовать

Я не уверен, почему вы пишете это, но вы также можете использовать itertools.permutations(), Оно использует yield поэтому ему не нужно строить весь список. — Ben Ruijl

Я еще не научился использовать yield. поэтому мне было интересно, есть ли способ сделать этот код без использования yield — brian Chiem

Почему бы вам не проверить Numpy .. Я думаю, что он предоставляет эти функции. Хотя не уверен — Surya

@БрайанЧим, itertools.permutations() использование yield в основном прозрачен для вас, так что дайте ему вихрь. Использовать list(itertools.permutations(. ) если вы не планируете перебирать его в for петля. — Brian Cain

10 ответы

Вы хотите сделать рекурсию, поэтому сначала вам нужно выяснить, как она будет работать. В данном случае это следующее:

И в качестве конечного условия:

Таким образом, рекурсия разбивает список на подсписки, каждый раз извлекая один элемент. Затем этот элемент добавляется в начало каждой из перестановок подсписка.

Итак, в псевдокоде:

Помогает ли это?

ответ дан 19 окт ’14, 17:10

поэтому для z = s без элемента a работает plst = permutations(s[1:]) — Брайан Чием

Да, но вы должны сделать это для каждого элемента s. Таким образом, следующий (с удаленной буквой «b») будет permutations(s[0] + s[2:]) . Обратите внимание, что в это подмножество включена буква «а». — Бен Руйл

Где рекурсивный вызов? Разве это не должно быть for each t in permutations(z): perm_list.append([a]+t]) ? — тобиас_к

@tobias_k: Ах да, я просмотрел это! Я исправил это сейчас. — Бен Руйл

я не уверен, что я должен поместить в эту часть perm_list.append([a] + t) я думаю, что это рекурсивный вызов, но я не уверен. я думал, что я должен поставить перестановки (s [1:]) + перестановки (s [0]) — Брайан Чием

Рекурсивно подумайте о базовом случае и стройте из этой интуиции.

1) Что происходит, когда есть только один символ «с»? Существует только одна перестановка этого элемента, поэтому мы возвращаем список, содержащий только этот элемент.

2) Как мы можем сгенерировать следующую перестановку, учитывая последнюю? Добавление дополнительной буквы «а» во всех возможных позициях в предыдущей перестановке «с» дает нам «са», «ас».

3) Мы можем продолжать строить все большие и большие перестановки, добавляя дополнительный символ во всех возможных позициях в каждой предыдущей перестановке.

Следующий код возвращает список из одного символа, если в строке один символ или меньше. В противном случае для всех перестановок, не включающих последний символ в строке s[-1], мы генерируем новую строку для каждой позиции, в которую мы могли бы включить этот символ, и добавляем новую строку к нашему текущему списку перестановок.

Когда вы потерялись в рекурсивной функции, вам следует нарисовать дерево вызовов. Следующая версия (вдохновленный ответом @Ben) сохраняет порядок ввода (если ввод в лексикографическом порядке, список перестановок будет, ‘012’ -> [‘012’, ‘021’, ‘102’, ‘120’, ‘201’, ‘210’] .

Следующая версия работает для строк и списков, обратите внимание, что шаг реконструкции отличается:

В качестве упражнения вы должны нарисовать дерево вызовов этих функций, вы что-то заметили?

ответ дан 08 апр.

Вы можете использовать функцию, которая перебирает индекс по списку и выдает список, состоящий из значения в индексе, за которым следуют перестановки остальных значений списка. Ниже приведен пример использования функций из Python 3.5+:

так что list(permutations(‘abc’)) возвращает:

ответ дан 15 мар ’19, в 17:03

Я знаю, что это тоже я, но я думаю, что некоторым людям будет легче понять это.

  1. В базовом случае вводится только один символ.
  2. Настройте цикл for, который перебирает каждую букву в строке.

Другой цикл for рекурсивно перебирает все остальные возможности.

ответ дан 06 дек ’19, 19:12

Вы можете назвать это по

ответ дан 16 окт ’17, 15:10

Это самое простое решение, которое я придумал.

Вы можете проверить это с помощью:

ответ дан 30 окт ’18, 17:10

Самый простой способ выполнить перестановку с помощью рекурсии — сначала представить дерево рекурсии для задачи.

Введите описание изображения здесь

базовый случай: если нам дан пустой список, перестановка будет [ [] ] Тогда мы просто хотим удалить элемент из списка и добавить его ко всем индексам остальной части списка.

Время: O(N!) #Это лучше, так как мы создаем N! элемент
Пробел O(N^2) #N кадров стека * N элементов в per_with_all

Создан 15 июля ’21, 09:07

Эти примеры кодов действительно полезны, но я обнаружил, что тестовый пример не удался, когда я выполнял кодовую практику на КодСигнал. в основном весь данный подход игнорирует наличие дубликатов.

Итак, если вы видите, в выводе есть следующие дубликаты:

Я немного изменил это здесь

Но этот ответ не подходит по временной сложности. Временная сложность при таком подходе: o(n^2)

Советы тем, кто программирует на VB & VBA

Все программные примеры, которые использовались в приведенных здесь советах, можно найти по адресу: www.visual.2000.ru/develop/vb/source/.

Совет 256. Программное обращение к CommonDialog

Если требуется выполнить выборку имени файла для операций открытия или закрытия, для этого обычно используется элемент управления CommonDialog. Однако в ряде случаев полезнее бывает выполнить прямое обращение к функциям GetOpenFileName и GetSaveFileName библиотеки COMDGL32.DLL. Например, если вы пишете собственный мастер по созданию проекта, то подключиться в проект с модулем кода гораздо удобнее, чем делать коррекцию кода модуля формы. Тем более что такая процедура будет единой для всего проекта.

В листинге 1 приведен один из вариантов реализации универсальной процедуры FileOpenSave поиска имени файла в режиме «Открыть/Сохранить», а также пример обращения к ней.

Совет 257. Как узнать, существует ли файл?

Проще всего сделать это следующей операцией в одну строчку:

Совет 258. Как выбрать имя каталога

В разных вспомогательных утилитах довольно часто встречается задача выборки имени файла или имени каталога. Например, если вы пишете утилиту по перекодировке текстовых файлов, будет достаточно предоставить пользователю возможность выбрать или конкретный файл, или каталог, в котором нужно преобразовать все файлы.

К сожалению, диалоговое окно Open (или DLL-функция GetOpenFileName) не позволяет выбирать только имя файла. Конечно, можно из этого имени по специальной команде пользователя сделать выделение каталога. А что делать, если нужный каталог содержит только подкаталоги?

Разумеется, лучшим вариантом является создание собственного диалогового окна, которое будет учитывать все режимы, необходимые в конкретной задаче. Но можно использовать и стандартное окно Open.

Для этого в поле File Name нужно просто ввести любое имя несуществующего в данном каталоге файла (например, QQQQ). Соответственно в программе, которая обращается к окну (например, с использованием функции FileOpenSave, о чем говорилось в предыдущем совете), напишется такой программный код:

Совет 259. Какие операторы лучше использовать: Print # или Write #?

В своем совете 228 мы привели пример утилиты Summa.vbp (представление числового значения прописью), которая, в частности, сохраняет введенные параметры (для последующего восстановления) в виде простого текстового файла. Данные последовательно записываются оператором Print #, а при запуске утилиты читаются оператором Input #.

В связи с этим наш читатель Константин Абакумов обратил внимание на то, что в справке Visual Basic подчеркивается следующее: «Для записи данных в файл, который в будущем планируется читать с помощью инструкции Input #, следует вместо инструкции Print # использовать Write #. Это гарантирует, что записанные данные будут корректно разделены и могут быть корректно прочитаны при наличии любых национальных настроек».

Это замечание совершенно справедливо (хотя конкретно в случае утилиты Summa — не существенно), однако порой Print # является предпочтительнее. Рассмотрим эту ситуацию подробнее.

Преимущества Write #

Предположим, вы хотите сохранить четыре переменные — дату, две символьные строки и число:

Очевидная проблема возникнет при чтении даты, записанной в файл в виде 26.02.00: программа просто не поймет, что это — дата. Можно решить этот вопрос, сделав следующую конструкцию чтения даты:

Однако здесь также имеется потенциальная опасность — нужно быть уверенным, что данные читаются и записываются в Windows с одинаковыми региональными установками. (Представьте себе, что вам нужно переслать файл с расчетными данными в виде текстового файла своему коллеге в США.)

Еще больше проблем возникнет с конструкцией:

В случае нашего примера вы получите следующие результаты при чтении:

Видно, что они отличаются от исходных значений. Если же использовать в операторе Print # в качестве разделителя в списке запятую, то получится следующий результат:

Если мы заменим оператор Print # на Write #, то все данные будут сохраняться и читаться верно, поскольку дата будет записываться в виде литерала #2000-02-26# (обратите внимание, что литералы даты хранятся в американском формате, независимо от региональных установок), строковые переменные — в двойных кавычках и все поля в текстовом файле будут разделены запятыми.

Но здесь есть очевидная проблема: если ваши строковые переменные содержат двойные кавычки, то будут происходить неприятные искажения данных. Например, вы ввели в текстовое поле название ЗАВОД «САЛЮТ» и хотите сохранить его значение в текстовом файле. Чтобы гарантированно избежать подобной ситуации, нужно проверять строки на наличие двойных кавычек и, в частности, автоматически их удалять (можно поставить соответствующий контроль при вводе данных) или менять на одинарные кавычки.

Преимущества Input #

Предположим, вам нужно сохранить в виде текстового файла числовой массив с переменными границами Arr (M, N). Конечно, можно воспользоваться оператором Write #:

Однако с таким текстовым файлом будет крайне неудобно работать, если потребуется изучать или корректировать его с помощью простого текстового редактора (такая задача встречается достаточно часто). Файл будет выглядеть гораздо лучше, если применить следующий код:

Таким образом, оператор Print # очень полезен в случае, когда нужно вывести в одну строку текстового файла набор данных переменной длины или просто большое число однородных данных.

В свое время мы именно в силу необходимости получения структурируемого текстового файла (хорошо читаемого в текстовом редакторе) полностью отказались от использования оператора Write #. Для беспроблемного применения Print # мы создали очень простой набор процедур, который имитировал Write — заключал в кавычки строки, писал даты в виде литералов, расставлял запятые в качестве разделителей.

Какой вариант удобнее? Это, конечно же, зависит от конкретной решаемой задачи.

Совет 260. Где хранить INI-файл

В данном случае мы имеем в виду файлы, в которых хранятся некоторые параметры приложения между его перезапусками. (В общем случае они могут иметь любое расширение и любую удобную для разработчика структуру.) Конечно, для хранения подобных файлов можно выделить специальный каталог, например системный Windows. Или вообще хранить подобные данные в файле Реестр. Однако, на наш взгляд, такая концентрация данных разных приложений в одном месте является довольно порочной практикой (к сожалению, именно она используется авторами Windows, а по их примеру — и многими независимыми разработчиками). В связи с этим можно привести несколько возражений: использование единого Реестра снижает производительность и надежность системы («падение» одного файла приводит к «падению» данных всех приложений), кроме того, резко усложняется проблема «удаления мусора».

Поэтому мы советуем создавать для отдельных приложений собственные INI-файлы. И хранить их лучше всего в одном каталоге с самим приложением — тогда вам не придется писать инструкции пользователям «Создайте каталог IniFolder для хранения файла MyApplication.INI». Более того, может оказаться удобным предоставить возможность использования нескольких вариантов INI-файлов (например, при работе нескольких пользователей). В этом случае вызов утилиты (через ярлык) может выполняться командной строкой:

Программный код обработки будет в этом случае иметь, например, такой вид:

При отладке приложений в среде командная строка задается в поле Command Line Arguments в диалоговом окне Project Properties|Make.

Совет 261. Как обеспечить совместимость VBA и VB

В статье об интеграции VBA в VB-приложения («Интеграция VBA в бизнес-приложения независимых разработчиков», КомпьютерПресс 3’2000) мы отмечали следующую проблему с отладкой приложений.

Если мы запускали созданное приложение (с уже интегрированным в него VBA) непосредственно в среде Visual Basic, то, перейдя затем в VBA, обнаруживали, что глобальный объект приложения CApplication (он создавался мастером VB Integration) недоступен. Если же создать загрузочный EXE-модуль, то с объектом можно будет нормально работать.

Для иллюстрации этой ситуации продемонстрируем несложный пример. При этом имеется в виду, что вы работаете с VB и у вас на компьютере установлен VBA 6.0 SDK 6.1.

В среде VB создайте самый простой проект — Standard EXE. Обратите внимание: у нас получилось вполне работоспособное приложение, которое просто загружает формы. Но нам для примера ничего больше и не нужно. Далее запустите VB Integration Wizard из меню Add-ins и пройдите все этапы его работы, просто нажимая кнопку Next (ничего не меняя в полях окон).

Итак, за полминуты мы создали приложение, которое само по себе ничего не умеет делать, но зато имеет среду VBA, где можно разрабатывать и выполнять автономные VBA-проекты любой сложности.

  1. Запустим наше приложение Project1, перейдем в среду VBA (Alt-F11) и напишем в окне Immediate:

Нажав Enter (выполнив эту строку), мы увидим сообщение: «Method or data member not found».

Теперь создадим EXE-модуль нашего проекта и повторим с ним пункт 1. Ошибки не будет, и мы увидим в окне Immediate имя нашего проекта — Project1.

Получается, что отлаживать макрокоманды, которые работают с объектами основного приложения, можно только в варианте EXE. Это, конечно, очень неудобно, особенно в том режиме, когда мы ведем разработку и отладку этих объектов.

Но, оказывается, есть очень простое решение этой проблемы. Нужно просто переименовать объект CApplication в Application, внеся также соответствующие изменения во все упоминания этого объекта, например используя команду Replace. (Еще проще сделать это в момент работы мастера VB Integration, исправив предлагаемое имя глобального объекта приложения.)

Теперь объект Project1.Application будет доступен и в среде VB, и при работе с EXE-модулем. Почему так получается, что в среде VB доступен только объект с именем Application, — непонятно. Но тем не менее это так!

Совет 262. Как контролировать макросы в шаблонах

В своем обзоре по MS Office 2000 (КомпьютерПресс 12’99) мы отмечали некоторые проблемы при использовании шаблонов в Word 2000. Так, при загрузке шаблонов в виде автономных документов или присоединенного файла из каталога Шаблоны пользователя не производилась проверка на наличие макрокода, хотя такой режим контроля был задан. Оказывается, проблема заключается в более детальных установках контроля за макрокодом.

Управление режимом контроля за наличием макрокода при загрузке документов производится в диалоговом окне Security[Безопасность] (команда меню Tools|Macro|Securiry [Сервис|Макрос|Безопасность]). На его вкладке Trusted Sources [Надежные источники] имеется флажок Trust all installed Add-ins and templates [Доверять всем установленным надстройкам и шаблонам]. Под «установленными» подразумеваются дополнения и шаблоны, помещенные в каталог «Шаблоны пользователя». (Конкретное имя этого каталога указывается в поле User Templates [Шаблоны пользователя] во вкладке File Locations [Расположение] диалогового окна Tools|Options [Сервис|Параметры].)

По умолчанию данный флажок установлен, поэтому все шаблоны из этого каталога не проверяются на наличие макрокода (подразумевается, что вы помещаете туда файлы, в которых точно уверены). Если вы все же хотите выполнять такую проверку, то очистите флажок.

В Word 97 такого специального режима для загрузки шаблонов не было. Но в начальной версии программы иногда имела место ошибка — когда шаблоны загружались без проверки на макрокод. Этот дефект уже устранен — заплатку, которая решает данную проблему, можно скачать по адресу http://www.microsoft.com/rus/download/wd97sp.htm.

Совет 263. Использование даты в SQL-запросах

В своей статье «Особенности обработки дат в Visual Basic» (КомпьютерПресс 07’99) мы обращали внимание читателей на необходимость учета национальных особенностей обработки дат. Вот еще один из примеров подобной ситуации.

При обращении к базе данных для выборки каких-то записей по дате нужно написать символьную строку приблизительно такого вида:

Обратите внимание, что дата задается здесь как литерал, но самое главное — литерал может быть представлен только в формате американской даты. Поэтому вариант, часто предлагаемый американскими авторами:

с российскими региональными установками работать не будет. Для этого требуется использовать функцию Format с заданием американского формата:

Здесь нужно обязательно в явном виде установить разделители в дате, так как, хотя мы и указали "MM/dd/yyyy" в Windows с российскими региональными установками, в символьном представлении даты будут записаны точки.

Совет 264. Программный сброс хранителя экрана

Наш читатель Владимир Чикин прислал нам такой вопрос: каким образом выключить хранитель экрана программным способом из приложения, чтобы вновь был виден программный интерфейс? Это бывает нужно, если приложение работает без использования диалога с пользователем (например, программа отслеживает данные, поступающие из COM-порта, или просто выполняет очень длительные вычисления) и требуется выдать сообщения о каких-либо критических событиях в программе.

Здесь видятся два варианта решений:

  1. Если приложение работает фактически в однозадачном режиме и вас интересует только проблема предохранения экрана (без какой-либо экзотической графики), то проще всего реализовать такой режим внутри программы, без использования автономных хранителей экрана.

Для этого создайте форму, на которую поместите элемент управления Label, содержащий какой-либо текст, а также элемент управления Timer, для которого установите свойство Interval как 1000 (то есть 1 секунда). Для формы установите свойства WindowState = Maximized, Border Style = None и выберите черный цвет в качестве фона BackColor. Теперь введите следующий код для вашей формы:

Соответственно в программе, когда потребуется погасить экран, нужно загрузить форму, а в необходимый момент — выгрузить ее.

Если требуется обеспечить такой режим, чтобы по щелчку мыши хранитель исчезал на некоторое время, а потом появлялся опять, то можно написать такой код формы:

  1. Но что же делать, если вам действительно нужно программно сбросить внешний «фирменный» хранитель экрана? В этом случае можно воспользоваться функцией keybd_event из состава Win API, которая имитирует манипуляции с клавиатурой. (Здесь также нужно упомянуть об аналогичной функции mouse_event для имитации мыши.)

Пример процедуры SendMyKey, которая обеспечивает имитацию записи в буфер указанного ASCI-символа, приведен на листинге 2. В этом случае для сброса внешнего хранителя экрана можно использовать такую программную конструкцию:

Мы не смогли понять почему, но посланный символ срабатывает только в случае, если программа потом выдает на экран еще какое-либо окно. Разумеется, если вы точно знаете, какой символ собираетесь имитировать, то можно обратиться напрямую к keybd_event, без дополнительных обращений к другим API-функциям для вычисления вспомогательных кодов. Для случая клавиши Tab это будет выглядеть следующим образом:

Совет 265. Как подключить VB-процедуры обратного вызова к API-функции

Оператор AddressOf, появившийся в VB версии 5.0, позволяет передавать указатель для определяемой пользователем подпрограммы, функции или свойства в API-функцию, которая затем может передавать различные данные в процедуру обратного вызова (callback procedure). Для передачи такого указателя в API-функцию следует использовать

в качестве аргумента в этой функции. Поэтому, например, чтобы заменить или расширить стандартную процедуру работы с сообщениями, можно написать такую подпрограмму:

где WindowProc является пользовательской процедурой. Подобная операция называется подключением обратного вызова. В этом случае аргумент WindowProc сможет перехватывать сообщения формы. В нашем случае для отключения пользовательской процедуры следует вызвать ту же самую API-функцию с указателем предыдущей процедуры приблизительно так:

При использовании ключевого слова AddressOf необходимо, однако, соблюдать следующие правила. Названия определяемых пользователем подпрограмм, функций или свойств, которые будут использоваться в качестве обратного вызова, должны следовать непосредственно за оператором AddressOf. Проект, в котором имеются подпрограммы, функции и свойства обратного вызова, должен содержать соответствующие описания API-функций и процедуры. Нельзя применять AddressOf ни с какими другими функциями, кроме определяемых пользователем подпрограмм, функций или свойств. Например, вы не можете использовать другую API-функцию или функцию из библиотеки типов. Обратный вызов должен находиться в стандартном модуле. И, наконец, последнее — определяемая пользователем подпрограмма или функция должна иметь тип Any либо Long.

Совет 266. Как избежать ошибок сравнения битовой маскировки при использовании API-функций в VB

При использовании API-функций достаточно часто возникает необходимость определить, содержат ли получаемые результаты определенный признак (flag) или нет. Для этого данный признак маскируется и применяется оператор And. Например, предположим, что мы хотим узнать, в каком состоянии находится текущее окно — развернуто оно или свернуто. Вначале получим установки этого окна с помощью API-функции GetWindowLong(), которую опишем в стандартном модуле следующим образом:

Затем поместим на форму командную кнопку и введем такой код в ее событие Click():

Теперь запустим наш пример на выполнение и щелкнем на кнопке. Приведенный выше код определяет, содержит ли значение стиля битовое значение признака. Если да, то логическое сравнение возвращает число, которое VB интерпретирует как True (Истина). В противном случае возвращается 0 или False (Ложь).

Ошибки же могут возникнуть, если мы попытаемся проверить исключение какого-либо признака. Так, предположим, мы хотим выполнить определенные действия, когда окно находится в свернутом состоянии. Попробуем просто написать:

(Конечно, в данном конкретном случае мы могли бы выполнить тестирование признака WS_MINIMIZE, но иногда API-функции не имеют признака, представляющего собой противоположную установку.) К сожалению, такой условный оператор всегда возвращает значение True. Это происходит потому, что, когда мы используем оператор Not с числом, VB возвращает значение этого числа с противоположным знаком минус 1. Например, выражение Not 15 возвращает -16, которое интерпретируется VB как True. В нашем примере с битовой маскировкой выражение Not (lWinStyle And WS_MAXIMIZE) для развернутого окна имеет ненулевое значение, которое опять оценивается как True.

Чтобы избежать появления подобного «глюка», можно использовать один из двух следующих операторов:

Совет 267. Используйте VB-объект RegExp для проверки синтаксиса адреса электронной почты

В современных приложениях часто бывает необходимо, чтобы пользователь вводил информацию о своей компании, включая адрес электронной почты. При этом нужно быть уверенным не только в том, что такой адрес содержит знак @ и точку, но и в том, что все остальные символы представлены буквами, числами или знаками подчеркивания. На первый взгляд такая задача может показаться не очень простой, если вы будете пользоваться только стандартными VB-функциями обработки строк. К счастью, в VB существует объект RegExp, который существенно упрощает работу.

Однако прежде чем приступить к использованию этого объекта в VB, следует загрузить библиотеку VBScript 5.0 DLL, которая находится по адресу: www.microsoft.com/msdownload/vbscript/scripting.asp

После установки библиотеки в диалоговом окне References в VB появится строка Microsoft VBScript Regular Expressions. Добавьте эту ссылку к проекту — и можно приступать к работе. Следующий код проверяет адрес электронной почты, который вводится в текстовом поле Text1:

Приведенный в этом коде шаблон может принимать любое количество числовых и буквенных символов, символов подчеркивания, десятичной точки и тире перед знаком @, но только числа, буквы и символы подчеркивания до и после точки.

Совет 268. Как осуществить прокрутку элемента управления ListView в VB до заданного элемента

Известно, что элемент управления ListView позволяет простым способом связать элементы списка со значками, рисунками и строками отчетов. С его помощью легко выбрать определенный элемент списка. Однако это не всегда означает, что данный элемент будет виден пользователю. Например, если список содержит много элементов, то для просмотра последнего из них необходимо пользоваться линейкой прокрутки. К счастью, элемент управления ListView предоставляет возможность программным образом перейти к заданному элементу.

Для каждого элемента списка существует метод EnsureVisible, при вызове которого указанный элемент списка выводится в видимой части элемента управления ListBox. Для иллюстрации поместите этот компонент на форму, а затем щелкните на нем правой кнопкой мыши и выберите команду Properties из быстрого меню. В диалоговом окне Properties Pages измените свойство View на 3 — lvwReport. Затем перейдите во вкладку Column Headers, выберите поле теста Insert Column и введите там «Какой элемент?». Щелкните OK. И наконец напишите следующий код для события Load формы:

Запустите проект на выполнение. VB откроет форму, выведет окно списка и выделит в нем одиннадцатый элемент.

Совет 269. Работа в VB с формулами, представленными в виде строковых переменных

Если до того, как начать программировать на VB, вы уже работали с Microsoft Access, то вы, вероятно, ощутили нехватку в VB очень удобного метода Eval, который вычисляет заданную строковую переменную, как если бы она была кодом. Так, в Access вы могли легко вычислять математические выражения, передаваемые как строки, например выражения подобного вида:

где iResult принимает значение 11.

Чтобы получить те же возможности в VB, вам, несомненно, пришлось обратиться к сложным функциям синтаксического разбора строк. Или же вы были вынуждены добавить к своему проекту библиотеку из Access, что существенно усложняет его для реализации столь простого метода.

Теперь, с выходом VB6, вам больше не придется прибегать к подобным ухищрениям, чтобы воспользоваться методом Eval, поскольку Microsoft включила его в элемент управления Script. С помощью этого компонента вы можете добавлять к своим приложениям возможность написания сценариев конечным пользователем. Потому-то для реализации данной возможности в состав Script и вошел метод Eval, благодаря которому вы сможете легко вычислять математические строковые переменные.

Элемент управления Script находится по адресу http://msdn.microsoft.com/scripting/. Загрузите его и выполните следующий простой пример, где для события Click командной кнопки введен такой код:

Здесь элемент управления SC1 вычисляет математическую формулу, вводимую в поле текста txtFormula.

Совет 270. Как сделать невидимым курсор мыши в VB-приложении

APi-функция ShowCursor предоставляет простой способ сделать невидимым курсор мыши:

Если вы зададите параметр bShow как 0, курсор мыши исчезнет, если как 1, — появится вновь. Только помните, что при использовании этой функции курсор просто становится невидимым, а это совсем не означает, что он отключен. Чтобы продемонстрировать, что мы имели в виду, добавим приведенное выше описание функции к проекту и введем следующий код для формы:

Запустим проект на выполнение. Щелкнем форму, и VB уберет с экрана курсор мыши. Снова щелкнем форму, и курсор появится вновь. Если бы курсор мыши был действительно отключен, то мы бы не смогли вернуть его на экран одним только щелчком формы. Теперь опять щелкнем форму, чтобы курсор сделался невидимым, и перетащим его к линейке меню интегрированной среды разработки VB. Когда невидимый курсор будет перемещаться от одной кнопки меню к другой, последняя будет приподниматься над поверхностью, сообщая о том, что она готова для щелчка. И действительно, вы по-прежнему можете пользоваться мышью для вызова команд меню или выбора объектов на экране.

If myStr = 'test', why does myStr[4] produce error out of range but myStr[4:] does not?

I’m using recursion to iterate through the values of a string. When I get past the last character, it’s allowing me to use that index position as an empty string «» instead of giving an error. Why is that?

produces an error

does not produce any error.

3 Answers 3

Slicing is not bounds-checked by the built-in types. If the array indices are out of bounds, it will automatically truncate then at the right places.

Tim Givois's user avatar

Because array accesses are defined such that it’s an error for a lone index to be out of range, but not for (part or all of) a slice to be. If any part of a slice is out of range, it simply yields no results, rather than triggering an error.

Because that’s how the language was designed. Python 3.0 documentation says about strings that

Attempting to use an index that is too large will result in an error. However, out of range slice indexes are handled gracefully when used for slicing.

Gerardo Cauich's user avatar

    Featured on Meta
Linked
Related
Hot Network Questions

Subscribe to RSS

To subscribe to this RSS feed, copy and paste this URL into your RSS reader.

Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.9.5.43611

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.

Начинаем_программировать_на_Python

чении состоит в применении цикла for. Вот общий формат:
for переменная in строковое_значение:

В данном формате переменная- это имя переменной, строковое_значение- строковый
литерал либо переменная, которая ссылается на строковое значение. Во время каждой ите­
рации цикла переменная будет ссылаться на копию символа в строковом значении, начиная
с первого символа. Мы говорим, что цикл выполняет последовательный перебор символов
в строковом значении. Вот пример:

name = 'Джулия'
for ch in name:

Переменная name ссылается на строковый литерал с шестью символами, поэтому цикл сде­
лает шесть итераций. Во время первой итерации цикла переменная ch будет ссылаться на

'д', во время второй итерации — на 'ж' и т. д. (рис. 8.1 ). Когда программный код исполнит­

ся, он покажет следующее:

На рис. 8.1 показано, как переменная ch ссылается на копию символа из строкового значения по
мере выполнения итераций цикла. Если в цикле поменять значение, на которое ссылается ch, то
это не повлияет на строковый литерал, на который ссылается переменная name. Для того чтобы

это продемонстрировать, взгляните на приведенный ниже фрагмент кода:

1 name = 'Джулия'
2 for ch in name:
3 ch = 'Х'
4 print(name)

Инструкция в строке 3 во время каждой итерации цикла повторно присваивает переменной ch

другое значение. Эта операция не влияет на строковый литерал 'Джулия', на который ссылается

переменная name, и не влияет на количество итераций цикла. Во время исполнения этого фраг­
мента кода инструкция в строке 4 напечатает:

В программе 8.1 показан еще один пример. Эта программа просит пользователя ввести стро­

ковое значение. Затем она применяет цикл for для обхода строкового значения, подсчиты­

вая количество появлений буквы Т (в верхнем или нижнем регистре).

Глава 8. Подробнее о строковых данных 429

1-я итерация for ch in name: 2-я итерация for ch in name:
print(ch) print(ch)

3-я итерация for ch in name: 4-я итерация for ch in name:
print(ch) print(ch)

5-я итерация for ch in name: 6-я итерация for ch in name:
print(ch) print(ch)

РИС. 8.1. Обход строкового литерала 'Джулия '

Программа 8.1 (count_Ts.py)

1 # Эта программа подсчитывает количество появлений
2 # буквы Т (в верхнем или нижнем регистре)
3 # в строковом значении.

5 def main():
6 # Создать переменную, в которой будет храниться количество.
7 # Переменная должна начинаться с О.
В count = О

10 # Получить от пользователя строковое значение.

11 my_string = inрut('Введите предложение: ')

13 # Подсчитать буквы Т.

14 for ch in my_string:

430 Глава В. Подробнее о строковых данных

17 'раз.')
18 # Напечатать результат.
19 print('Бyквa Т появляется', count,
20
21 # Вызвать главную функцию.
22 main ()

Введите предложение : Кiro не ходи'!', '1'0'1' и не падает. 1Enter: 1

5Буква Т появляется раз(а) .

Еще один способ получить доступ к отдельным символам в строковом значении реализуется
при помощи индекса. Каждый символ в строковом значении имеет индекс, который задает
его позицию. Индексация начинается с О, поэтому индекс первого символа равняется О, ин­

декс второго символа равняется 1 и т. д. Индекс последнего символа в строковом значении
равняется количеству символов в строковом значении минус 1. На рис. 8.2 показаны индек­
сы для каждого символа в строковом литерале ' Ромашки белые'. Строковый литерал имеет
13 символов, поэтому индексы символов варьируются от О до 12.

Индекс можно использовать для получения копии отдельного символа в строковом зна­

my_string = 'Ромашки белые'
ch = my_string[б]

Выражение my_ str ing [6 J во второй инструкции возвращает копию символа из переменной

my_ string в индексной позиции 6. После исполнения этой инструкции переменная ch будет
ссылаться, как показано на рис. 8.3.

'Ромашки белые my_string

о 1 2 3 4 5 6 7 8 9 10 11 12

РИС. 8.2. Индексы строкового значения РИС. 8.3. Получение копии символа из строкового значения

Вот еще один пример:

my_string = 'Ромашки белые'
print(my_string[O], my_string[б], my_string[lO])

Этот фрагмент кода напечатает следующее:

В качестве индексов можно также использовать отрицательные числа. Это делается для
идентификации позиций символа относительно конца строкового значения. Для определе­

ния позиции символа интерпретатор Python прибавляет отрицательные индексы к длине
строкового значения. Индекс -1 идентифицирует последний символ в строковом значении,

Глава 8. Подробнее о строковых данных 431

-2 идентифицирует предпоследний символ и т. д. Приведенный ниже фрагмент кода пока­

my_string = 'Ромашки белые'
print(my_string[-1], my_string[-2], my_string[-13])

Этот фрагмент кода напечатает следующее:

Исключение IndexError происходит при попытке применить индекс, который находится вне

диапазона конкретного строкового значения. Например, строковый литерал 'Бостон' имеет

6 символов, поэтому его допустимые индексы находятся в пределах от О до 5. (Допустимые
отрицательные индексы находятся между -1 и -6.) Вот пример кода, который демонстриру­

ет исключение IndexError:

city = 'Бостон'
print (city [6])

Данный тип ошибки, скорее всего, произойдет, когда цикл неправильно зайдет за пределы

конца строкового литерала:

city = 'Бостон'
index = О
while index < 7:

print(city[index])
index += 1

Во время последней итерации этого цикла переменной index будет присвоено значение 6,

которое является недопустимым индексом для строкового литерала 'Бостон'. В результате

функция print вызовет исключение IndexError.

В главе 7 вы познакомились с функцией len, которая возвращает длину последовательности.

Функция len также используется для получения длины строкового значения. Приведенный

ниже фрагмент кода это демонстрирует:

Вторая инструкция вызывает функцию len, передавая переменную city в качестве аргумен­

та. Функция возвращает 6, т. е. длину строкового литерала 'Бостон'. Это значение присваи­

вается переменной size.

Функция len в особенности полезна для предотвращения ситуаций, когда циклы заходят за

пределы конца строкового значения:

city = 'Бостон'
index = О
while index < len(city):

print(city[index])
index += 1

432 Глава В. Подробнее о строковых данных

Обратите внимание, что цикл повторяется до тех пор, пока индекс меньше длины строково­
го значения. Это вызвано тем, что индекс последнего символа в строковом значении всегда

на 1 меньше его длины.

Конкатенация строковых данных

Распространенной операцией, выполняемой над строковыми данными, является их конка­
тенация, или присоединение одного строкового значения в конец другого. В предыдущих
+главах вы видели примеры, в которых используется оператор для конкатенации строковых

значений. Оператор + порождает строковое значение, которое является объединением двух

других строковых значений, используемых в качестве его операндов. Приведенный ниже
интерактивный сеанс это демонстрирует:

Строка 1 конкатенирует строковые значения 'Привет, ' и 'мир! ', чтобы создать строковое

значение 'Привет, мир!'. Полученный результат присваивается переменной message. Стро­

ка 2 печатает строковое значение, на которое ссылается переменная message. Вывод показан
в строке 3.

Вот еще один интерактивный сеанс, который демонстрирует конкатенацию:

1 >>> first_name = 'Эмили' IEnterl
2 >>> last_name = 'Егер' IEnterl
3 >>> full name = first name + ' ' + last_name IEnterl
4 >>> print(full_name) IEnterl
5 Эмили Егер
6 >>>

Строка 1 присваивает переменной first_ name строковый литерал 'Эмили'. Строка 2 при­
сваивает переменной last_ name строковый литерал 'Егер'. Строка 3 порождает строковое

значение, которое является конкатенацией переменной first_name, потом пробела и затем
переменной last_ name. Получившееся строковое значение присваивается переменной

full _ name. Строка 4 печатает строковое значение, на которое ссылается переменная
full_name. Вывод показан в строке 5.

Для выполнения конкатенации можно также использовать оператор +=. Приведенный ниже
интерактивный сеанс это демонстрирует:

1 >>> letters = 'абв' IEnterl
2 >>> letters += 'где' IEnterl
3 >>> print(letters) IEnterl
4 абвгде
5 >>>

Инструкция в строке 2 выполняет конкатенацию строковых литералов. Она работает так же,

letters = letters + 'где'

Глава В. Подробнее о строковых данных 433

После исполнения инструкции в строке 2 переменная letters будет ссылаться на строковое

значение 'абвгде'. Вот еще один пример:

>>> narne = 'Келли' [Enter[ # имя 'Келли'
>>> narne += 1 1 [Enter [ # имя
>>> narne += 'Ивонна' [l11_tii) # имя 'Келли 1
>>> narne += 1 ' [ЕПЩ] # имя 'Келли Ивонна'
>>> narne += 'Смит' [lnter] # ИМЯ
>>> print(narne) е ''Келли Ивонна

Келли Ивонна Смит 'Келли Ивонна Смит'

Следует иметь в виду, что операнд с левой стороны от оператора +=должен быть сущест­
вующей переменной. Если указать несуществующую переменную, то будет вызвано исклю­

это немутирующие последовательности

В Python данные строкового типа являются немутирующими последовательностями, т. е.

после создания их нельзя изменить. Некоторые операции, такие как конкатенация, произво­
дят впечатление, что они видоизменяют строковые данные, но в действительности этого не

происходит. Например, взгляните на программу 8.2.

Программа 8.2 ] (concatenate.py)

1 # Эта программа конкатенирует строковые значения.

3 def rnain () :
4 narne = 'Кармен'
5 print('Имя', narne)
6 narne = narne + ' Браун'
7 print ('Теперь имя', narne)
8
9 # Вызвать главную функцию.
1О rnain ()

Имя Кармен
Теперь имя Кармен Браун

Как показано на рис. 8.4, инструкция в строке 4 присваивает переменной narne строковый
литерал 'Кармен'. Инструкция в строке 6 присоединяет к строковому литералу 'Кармен'
строковый литерал 'Браун' и присваивает результат переменной narne (рис. 8.5). Как видно

из рисунка, исходное строковое значение 'Кармен' не изменилось. Вместо этого создается и

присваивается переменной narne новое строковое значение, содержащее 'Кармен Браун'.

(Исходный строковый литерал 'Кармен' больше не используется, потому что ни одна пере­

менная на него не ссылается. Интерпретатор Python в конечном счете удалит это неисполь­

зуемое строковое значение из оперативной памяти.)

434 Глава В. Подробнее о строковых данных

name = name + 'Браун'

=name 'Кармен' name

— E Jname Кармен Браун

РИС. 8.4. Строковый литерал 'Кармен' РИС. 8.5. Строковый литерал 'Кармен Браун'
присвоен переменной name присвоен переменной name

fl'J Поскольку строковые данные являются немутирующими последовательностями, применять
выражение в форме строка [Иiщекс] с левой стороны оператора присваивания нельзя. На­
пример, приведенный ниже фрагмент кода вызовет ошибку:

# Присвоить строковый литерал 'Билл' переменной friend.
friend = 'Билл'

#Можно ли поменять первый символ на 'У'?

friend[O] = 'У' # Нет, это вызовет ошибку!

Последняя инструкция в этом фрагменте кода вызовет исключение, потому что она пытается

изменить первый символ в строковом литерале ' Билл ' .

8.1. Допустим, что переменная name ссылается на строковое значение. Напишите цикл for,

который напечатает каждый символ в строковом значении.

8.2. Каков индекс первого символа в строковом значении?
8.3. Каков индекс последнего символа в строковом значении, которое имеет 1О символов?
8.4. Что произойдет, если попытаться применить для доступа к символу в строковом зна-

чении недопустимый индекс?

8.5. Как найти длину строкового значения?
8.6. Что не так с приведенным ниже фрагментом кода?

8.2 Нарезка ст оковых значений

Выражения среза используются для извлечения диапазона символов из строкового зна­

В главе 7 вы узнали, что срез является диапазоном элементов, извлекаемых из последова­

тельности. При взятии среза из строкового значения в результате получается диапазон сим­
волов строкового значения. Срезы строковых значений также называются подстроками.

Для того чтобы получить срез строкового значения, пишут выражение в приведенном ниже
общем формате:

Глава 8. Подробнее о строковых данных 435

В данном формате начало- это индекс первого символа в срезе, конец- индекс, отме­
чающий конец среза. Это выражение возвращает строковое значение, содержащее копию
символов с начала до конца (но не включая последний). Например, предположим, что име­
ется фрагмент кода:

full name = 'Петти Линн Смит'
middle name = full_name[б:lO]

Вторая инструкция присваивает переменной middle_ name строковое значение 'линн'.

Если в выражении среза опустить индекс начала, то Python будет использовать О в качестве

начального значения индекса. Вот пример:

full name = 'Петти Линн Смит'
first_name = full_name[:S]

Вторая инструкция присваивает переменной first _ name строковое значение 'Петти'.

Если в выражении среза опустить индекс конца, то Python будет использовать длину строко­

вого значения в качестве индекса конца. Вот пример:

full name 'Петти Линн Смит'
last name
full name [11 : ]

Вторая инструкция присваивает переменной last_ name строковое значение 'Смит'.
Что присвоит переменной my string приведенный ниже фрагмент кода? Как вы думаете?

full name 'Петти Линн Смит'
my_string
full _ name [: ]

Вторая инструкция присваивает переменной my_string весь строковый литерал 'Петти Линн
Смит ' . Эта инструкция эквивалентна:

my_string = full_name[O : len(full_name)]

Примеры взятия срезов, которые мы видели до сих пор, демонстрируют получение срезов
символов, расположенных подряд друг за другом. Выражения среза также могут иметь
величину шага, который позволяет пропускать символы в строковом значении. Вот пример
программного кода, в котором используется выражение среза с величиной шага:

Третье число в скобках является величиной шага. Примененная в этом примере величина

шага 2 приводит к тому, что срез содержит каждый второй символ из заданного диапазона

в строковом значении. Этот фрагмент кода напечатает следующее:
АВДЁЗЙПНПСУХЧЩЫЭЯ

В качестве индексов в выражениях среза также можно использовать отрицательные числа,
чтобы ссылаться на позиции относительно конца строкового значения. Вот пример:

full name 'Петти Линн Смит'
last name
full name [-4: ]

Вспомните, что Python прибавляет отрицательный индекс к длине строкового значения, что­

бы ссылаться на позицию по этому индексу. Вторая инструкция в этом фрагменте кода при­

сваивает переменной las t _ name строковое значение 'Смит'.

436 Глава В. Подробнее о строковых данных

ПРИМЕЧАНИЕ
Недопустимые индексы в выражениях среза не вызывают исключение. Например:

• если индекс конца задает позицию за пределами конца строкового значения, то Python вместо

него будет использовать длину строкового значения;

• если индекс начала задает позицию до начала строкового значения, то Python вместо него

будет использовать О;

• если индекс начала больше индекса конца, то выражение среза вернет пустое строковое зна­

Извлечение символов из строкового значения

В университете каждому студенту присваивается регистрационное имя для входа в систему .
Это имя используется студентом для регистрации в компьютерной системе кампуса. В рам­
ках вашего сотрудничества с университетским подразделением по информационным техно­
логиям вас попросили написать программный код, который генерирует для студентов сис­
темные имена для входа в систему. Вы будете использовать приведенный ниже алгоритм

генерации имени для входа в систему:

1. Получить первые три буквы имени студента. (Если длина имени меньше трех букв, то

использовать все имя.)

2. Получить первые три буквы фамилии студента. (Если длина фамилии меньше трех букв,

то использовать всю фамилию.)

3. Получить последние три символа идентификационного номера студента. (Если длина

идентификационного номера меньше трех символов, то использовать весь идентифика­
ционный номер.)

4. Конкатенировать три набора символов для генерации имени для входа в систему.

Например, если имя студента — Аманда Спенсер, ее идентификационный номер —
ENG672 l, то ее имя для входа в систему будет АмаСпе721. Вы решаете написать функцию

ge t _ l ogin_ name, которая в качестве аргументов принимает имя, фамилию и идентификаци­

онный номер студента и возвращает имя для входа в систему в виде строкового значения .

Вы собираетесь сохранить эту функцию в модуле login.py. Этот модуль затем можно импор­
тировать в любую программу Python, которая должна генерировать имя для входа в систему .
В программе 8.3 показан соответствующий код модуля login.py.

Программа 8.3 (login.py)

1 # Функция get_login_name принимает имя, фамилию и

2 # идентификационный номер в качестве аргуме н т о в.

3 # Он а в озвращает имя для вх ода в сист ему .

5 de f get l og in_ name (firs t, l ast , idnшnЬer ):

6 # Получит ь первые три буквы име ни.

7 3# Если длина имени меньше букв, т о

8 # сре з вернет в се имя целиком .

9 setl = fir st [O : 3]

Глава 8. Подробнее о строковых данных 437

10
11 # Получить первые три буквы фамилии.
12 # Если длина фамилии меньше 3 букв, то
13 # срез вернет всю фамилию целиком.
14 set2 = last[O : 3)
15
16 # Получить последние три буквы фамилии идентификатора.
17 #Если длина идентификатора меньше 3 символов, то
18 # срез вернет весь идентификатор целиком.
19 set3 = idnumЬer(-3 :]
20
21 # Собрать воедино наборы символов.
22 login_name = setl + set2 + set3
23
24 # Вернуть имя для входа в систему.
25 return login_name

Функция get_ login_ name принимает три строковых аргумента: имя, фамилию и идентифи­

кационный номер. Инструкция в строке 9 применяет выражение среза для получения первых

трех символов строкового значения, на которое ссылается параметр f i r s t , и присваивает
эти символы как строковое значение переменной setl. Если длина строкового значения, на

которое ссылается параметр first, меньше трех символов, то значение 3 будет недопусти­
мым конечным индексом. Если это так, то Python будет использовать в качестве конечного

индекса длину строкового значения, и выражение среза вернет все значение целиком.

Инструкция в строке 14 использует выражение среза для получения первых трех символов

строкового значения, на которое ссылается параметр l a s t , и присваивает эти символы как
строковое значение переменной set2. Если длина строкового значения, на которое ссылает­
ся параметр last, меньше трех символов, то будет возвращено все значение целиком.

Инструкция в строке 19 использует выражение среза для получения последних трех симво­

лов строкового значения, на которое ссылается параметр idnumЬer, и присваивает эти сим­

волы как строковое значение переменной set3. Если длина строкового значения, на которое

ссылается параметр idпumЬer, меньше трех символов, то значение -3 будет недопустимым
начальным значением индекса. Если это так, то Python будет использовать О в качестве на­

чального значения индекса.

Инструкция в строке 22 присваивает конкатенацию переменных setl, set2 и set3 перемен­
ной login_ name. Эта переменная возвращается в строке 25. Программа 8.4 демонстрирует

Программа 8.4 (generate_login.py)

1 # Эта программа получает имя и фамилию пользователя
2 # и идентификационный номер студента. На основе этих данных
3 # она генерирует имя для входа в систему.
4
5 import login
6

438 Глава 8. Подробнее о строковых данных

7 def main () :
#8 Получить имя, фамилию и ИД-номер пользователя.
9 first = input ('Введите свое имя: ')
10 last = input ('Введите свою фамилию: ')
11 ')idnumЬer = inрut('Введите свой номер студента:
12
13 # Получить имя для входа в систему.
14 print ('Ваше имя для входа в систему:')
15 print(login.get_login_name(first, last, idnumЬer))
16
17 #Вызвать главную функцию.
18 main ()

Вывод 1 программы (вводимые данные выделены жирным шрифтом)
Введите свое имя : XoJ1nи 1 Enter 1

Введите свою фамилию : Гэ.цдис 1Enter 1
Введите свой номер студе нта : CSC34899 I Enter l

Ваше имя для входа в систему :
ХолГэд899

Вывод 2 программы (вводимые данные выделены жирным шрифтом)

Введите свое имя : Эл 1 Enterl
Ввеш

те свою фамилию :

сииано 1Enter 1
Введите свой номер студента: 8104497 1Enter l

Ваше имя для входа в систему:
ЭлКус497

8.7. Что покажет приведенный ниже фрагмент кода?

mystring = 'aЬcdefg'
print(mystring[2:5])

8.8. Что покажет приведенный ниже фрагмент кода?

8.9. Что покажет приведенный ниже фрагмент кода?

mystring = 'abcdefg'
print (mystring [: 3] )

8.10. Что покажет приведенный ниже фрагмент кода?

mystring = 'abcdefg'
print(mystring[:])

Глава 8. Подробнее о строковых данных 439

8.3 е ка пои к и манипуляция строковь ми данными

Python предоставляет операторы и методы проверки и поиска внутри строковых данных,

а также получения модифицированных копий строковых данных.

Проверка строковых значений при помощи in и not in

В Python оператор in используется с целью определения, содержится ли одно строковое

значение в другом. Вот общий формат выражения с использованием оператора in с двумя

строковое_значениеl in строковое_значение2

строковое_значениеl и строковое_значение2 могут быть либо строковыми литералами, либо
переменными, которые ссылаются на строковые значения. Это выражение возвращает исти­
ну, если строковое_значениеl найдено в строковом_значении2. Например, взгляните на
фрагмент кода:

t ext = 'Во семьде с ят с емь лет назад'
if 'семь' in text:

print ('Строковое значение "семь" найдено. ')
else:

print ('Строковое значение "семь" не найдено.')

Этот фрагмент кода определяет, содержит ли строковое значение 'Восемьде сят семь лет

назад' подстроку ' семь ' . Если исполнить этот фрагмент кода, то он покажет:

Строковое значение "семь" найдено.

Для проверки, что строковое значение не содержится в другом строковом значении, можно

применить оператор not in. Вот пример:

name s = 'Билл Джо анна Сьюзен Крис Хуан Кэти'
if 'Пьер' no t in na mes :

print ('Пьер не найден. ')
else:

Если исполнить этот фрагмент кода, то он покажет:

Пь ер не найде н.

Из главы 6 известно, что метод — это функция, которая принадлежит объекту и выполняет
некоторую операцию с использованием этого объекта. Объекты строкового типа в Python

имеют многочисленные методы 1 • В этом разделе мы рассмотрим несколько строковых мето­
дов для выполнения следующих типов операций:

1 В этой книге мы не охватим все строковые методы. Описание всех строковых методов см. в документации

Python на сайте www.python.org.

440 Глава В. Подробнее о строковых данных

+ проверка строковых значений;
+ выполнение различных модификаций;
+ поиск подстрок и замена последовательностей символов.

Вот общий формат вызова строкового метода:

строковая_переменная. метод (аргументы)

В данном формате строковая переменная- это переменная, которая ссылается на строко­
вое значение, метод- имя метода, который вызывается, аргументы- один или несколько
передаваемых в метод аргументов. Давайте рассмотрим несколько примеров.

Методы проверки строковых значений

Строковые методы, перечисленные в табл. 8.1, проверяют строковое значение в отношении

определенных свойств. Например, метод isdigit () возвращает истину, если строковое зна­

чение содержит только цифры. В противном случае он возвращает ложь. Вот пример:

stringl = '1200'
if stringl.isdigit():

print(stringl, 'содержит только цифры.')
else:

print(stringl, 'содержит символы, отличные от цифр.')

Этот фрагмент кода выведет на экран:

1200 содержит только цифры.

Вот еще один пример:

string2 = '12ЗаЬс'
if string2.isdigit():

print (string2, 'содержит только цифры.')
else:

print(string2, 'содержит символы, отличные от цифр.')

Этот фрагмент кода выведет:

123аЬс содержит символы, отличные от цифр.

Таблица 8.1. Несколько методов проверки строкового значения

isalnum () Возвращает истину, если строковое значение содержит только буквы алфавита или цифры
isalpha () и имеет по крайней мере один символ. В противном случае возвращает ложь
isdigit ()
islower () Возвращает истину, если строковое значение содержит только буквы алфавита и имеет
по крайней мере один символ. В противном случае возвращает ложь

Возвращает истину, если строковое значение содержит только цифры и имеет по крайней
мере один символ. В противном случае возвращает ложь

Возвращает истину, если все буквы алфавита в строковом значении находятся в нижнем
регистре, и строковая последовательность содержит по крайней мере одну букву алфавита.
В противном случае возвращает ложь

Глава 8. Подробнее о строковых данных 441

Таблица 8.1 (окончание) •

isspace () Возвращает истину, если строковое значение содержит только пробельные символы
и имеет по крайней мере один символ. В противном случае возвращает ложь. (Пробельны-
———
ми символами являются пробелы, символы новой строки (\n) и символы табуляции(\ t).)
isupper ()

Возвращает истину, если все буквы алфавита в строковом значении находятся в верхнем
регистре, и строковая последовательность содержит по крайней мере одну букву алфавита.
В противном случае возвращает ложь

Программа 8.5 демонстрирует несколько строковых методов проверки. Она просит пользо­

вателя ввести строковое значение и затем выводит различные сообщения в зависимости от

возвращаемого методами значения.

JПрограмма 8.5 (stгiпg_test.py)

1 # Эта программа демонстрирует несколько строковых методов проверки.

4 # Получить от пользователя строковое значение.

5 user string inрut('Введите строковое значение: ')

6
7 print('Boт, что обнаружено в отношении введенного значения:')
8

9 # Проанализировать строковое значение.
10 if user string.isalnurn():
11 print ('Эта строка содержит буквы или цифры.')
12 if user_string.isdigit():
13 print ('Эта строка содержит только цифры.')
14 if user_string.isalpha():
15 print ('Эта строка содержит только буквы алфавита.')
16 if user string.isspace():
17 print ('Эта строка содержит только пробельные символы.')
18 if user_string.islower():
19 print('Bce буквы в строке находятся в нижнем регистре.')
20 if user string.isupper():
21 print('Bce буквы в строке находятся в верхнем регистре.')
22
23 # Вызвать главную функцию.
24 rnain ()

Вывод 1 программы (вводимые данные выделены жирным шрифтом)

Введите строковое значение : абв j Enter l

Вот , что обнаружено в отношении введенного значения :
Эта строка содержит буквы или цифры .
Эта строка содержит только буквы алфавита .
Все буквы в строке находятся в ниж.нем регистре .

442 Глава 8. Подробнее о строковых данных

Вывод 2 программы (вводимые данные выделены жирным шрифтом)

Введите строковое значение : 123 1Enter 1

Вот , что обнаружено в отношении введенного значения :
Эта строка содержит буквы или цифры .
Эта строка содержит только цифры .

Вывод 3 программы (вводимые данные выделены жирным шрифтом)
Введите строковое значение : 123АБВ 1Enter 1

Вот , что обнаружено в отношении введенного значения :
Эта строка содержит буквы J.UIИ цифры .
Все буквы в строке находятся в верхнем регистре .

Несмотря на то что строковые данные являются немутирующими последовательностями,

т. е. их нельзя изменить, они имеют много методов, которые возвращают их видоизменен­

ные версии. В табл. 8.2 приводится несколько таких методов.

Таблица 8.2. Методы модификации строкового значения

lower () Возвращает копию строкового значения, в котором все буквы преобразованы в ниж-
ний регистр. Любой символ, который уже находится в нижнем регистре или не явля-
lstrip () ется буквой алфавита, остается без изменения

lstrip (символ) Возвращает копию строкового значения, в котором все ведущие пробельные симво-
лы удалены. Ведущими пробельными символами являются пробелы, символы новой
rstrip ()
строки (\n) и символы табуляции(\ t), которые появляются в начале строкового

значения
rstrip (символ)
Аргументом символ является строковое значение, содержащее символ. Возвращает
strip ()
strip (символ) копию строкового значения, в котором удалены все экземпляры символа, появляю-
upper () щиеся в начале строкового значения

Возвращает копию строкового значения, в котором все замыкающие пробельные
символы удалены. Замыкающими пробельными символами являются пробелы,

символы новой строки (\n) и символы табуляции (\t), которые появляются в конце

Аргументом символ является строковое значение, содержащее символ. Возвращает

копию строковой последовательности, в которой удалены все экземпляры символа,

появляющиеся в конце строкового значения

Возвращает копию строкового значения, в котором удалены все ведущие —
и замыкающие пробельные символы

Возвращает копию строкового значения, в котором удалены все экземпляры симво-

ла, появляющиеся в начале и конце строкового значения


Возвращает копию строкового значения, в котором все буквы преобразованы в верх-

ний регистр. Любой символ, который уже находится в верхнем регистре или не явля-
ется буквой алфавита, остается без изменения

Глава 8. Подробнее о строковых данных 443

Например, метод lower () возвращает копию строкового значения, в котором все буквы пре­

образованы в нижний регистр. Вот пример:

letters = 'ЬЭЮЯ'
print(letters, letters.lower())

Этот фрагмент кода напечатает

Метод upper () возвращает копию строкового значения, в котором все буквы преобразованы

в верхний регистр. Вот пример:

letters = 'абвг'
print(letters, letters.upper())

Этот фрагмент кода напечатает

Методы lower () и upper () полезны для выполнения нечувствительных к регистру сравне­

ний строк. Операции сравнения строковых значений регистрочувствительны, т. е. символы
верхнего регистра и символы нижнего регистра различны. Например, в регистрочувстви­

тельном сравнении строковое значение 'абв' не считается равным значению 'АБВ' или

значению 'Абв ', потому что регистр символов отличается. Иногда удобнее выполнять

нечувствuтелыюе к регистру сравнение, в котором регистр символов игнорируется. В та­

'.ком случае строковое значение 'абв' считается таким же, что 'АБВ' и 'Абв

Например, взгляните на приведенный ниже фрагмент кода:

print ('Привет')
print ('Желаете это увидеть еще раз?')
again = input('д =да, все остальное= нет:

Обратите внимание, что последняя инструкция в цикле просит пользователя ввести д, чтобы

увидеть сообщение еще раз. Цикл повторяется до тех пор, пока выражение again. lower ()
'д' является истинным. Выражение будет истинным, если переменная again будет

Как показано ниже, аналогичные результаты можно достигнуть, используя метод upper () :

print ('Желаете это увидеть еще раз?')

again = input('д =да, все остальное= нет: ')

Программам очень часто требуется выполнять поиск подстрок, или строковых данных,
которые появляются внутри других строковых данных. Например, предположим, что вы от­

крыли документ в своем текстовом редакторе, и вам нужно отыскать слово, которое где-то

в нем находится. Искомое вами слово является подстрокой, которая появляется внутри бо­
лее крупной последовательности символов, т. е. документе.

444 Глава 8. Подробнее о строковых данных

В табл. 8.3 перечислены некоторые строковые методы Python, которые выполняют поиск

подстрок, а также метод, который заменяет найденные подстроки другой подстрокой.

Таблица 8.3. Методы поиска и замены

Метод Описание
endswith(пoдcтpoкa)
Аргумент подстрока — это строковое значение. Метод возвращает истину,
find (подстрока)
если строковое значение заканчивается подстрокой —
replace (старое, новое)
Аргумент подстрока — это строковое значение. Метод возвращает
startswith(пoдcтpoкa)
наименьший индекс в строковом значении, где найдена подстрока.

1 Если подстрока не найдена, то метод возвращает -1

Аргументы старое и новое — это строковые значения. Метод возвращает

копию строкового значения, в котором все экземпляры старых подстрок
заменены новыми подстроками

Аргумент подстрока — это строковое значение. Метод возвращает истину,

если строковое значение начинается с подстроки

Метод endswi th () определяет, заканчивается ли строковое значение заданной подстрокой.

filename = input ('Введите имя файла: ')
if filename.endswith(' .txt'):

print('Этo имя текстового файла.')

elif filename.endswith(' .ру'):
print('Этo имя исходного файла Python. ')

elif filename.endswith(' .doc'):

print('Этo имя документа текстового редактора.')

else:
print ('Неизвестный тип файла. ')

Метод startswi th () работает как метод endswi th (), но определяет, начинается ли строковое

значение с заданной подстроки.

Метод find () отыскивает заданную подстроку в строковом значении и возвращает наи­

меньшую индексную позицию подстроки, если она найдена. Если подстрока не найдена, то

метод возвращает -1. Вот пример:

string = 'Восемьдесят семь лет назад'
position = string.find('ceмь')
if position != -1:

print('Cлoвo "семь" найдено в индексной позиции', position)
else:

Этот фрагмент кода покажет

15Слово "семь" найдено в индексной позиции

Метод replace () возвращает копию строкового значения, где каждое вхождение заданной

подстроки было заменено другой подстрокой. Например, взгляните на приведенный ниже
фрагмент кода:

Глава 8. Подробнее о строковых данных 445

string = 'Восемьдесят семь лет назад'
new_string = string.replace('лeт', 'дней')
print(new_string)

Этот фрагмент кода покажет

Восемьдесят семь дней назад

Анализ символов в пароле

В университете пароли для компьютерной системы кампуса должны удовлетворять приве­
денным ниже требованиям:

+ пароль должен иметь как минимум семь символов;
+ должен содержать как минимум одну букву в верхнем регистре;
+ должен содержать как минимум одну букву в нижнем регистре;
+ должен содержать как минимум одну цифру.

Во время создания студентом своего пароля допустимость пароля должна быть проверена,
чтобы он гарантированно удовлетворял этим требованиям. Вас попросили написать
программный код, который выполняет эту проверку. Вы решаете написать функцию

valid_password, которая принимает пароль в качестве аргумента и возвращает истину либо

ложь, чтобы указать, является ли он допустимым. Вот алгоритм функции в псевдокоде:

функция valid_password:
Назначить переменной correct_length значение false.
Назначить переменной has_uppercase значение false.
Назначить переменной has lowercase значение false.
Назначить переменной has_digit значение false.

Если пароль имеет длину семь символов или больше:

Назначить переменной correct_length значение true

для кЮIЩого символа в пароле:

если этот символ является буквой в верхнем регистре:

Назначить переменной has_uppercase значение true.

если этот символ является буквой в нижнем регистре:

Назначить переменной has_lowercase значение true.

если этот символ является цифрой:

Назначить переменной has_digit значение true.
Если correct_length и has_uppercase и has_lowercase и has digit:

Назначить переменной is valid значение true.

Назначить переменной is valid значение false.

Ранее (в предыдущей рубрике "В центре внимания'1 вы создали функцию get_ login_name
и сохранили ее в модуле login. Поскольку задача функции valid_password связана с задачей
создания учетной записи студента, вы решаете разместить функцию valid_password в том

же модуле login. В программе 8.6 приведен модуль входа в систему login, в который до­
бавлена функция valid_password. Функция начинается в строке 34.

446 Глава 8. Подробнее о строковых данных

Программа 8.6 (login2.py)

1 # Функция get_login_name принимает имя, фамилию
2 # и идентификационный номер в качестве аргументов.
3 # Она возвращает имя для входа в систему.
4
5 def get login_name(first, last, idnumЬer):
6 # Получить первые три буквы имени.
7 # Если длина имени меньше 3 букв, то
8 # срез вернет все имя целиком.
9 setl = first[O : 3]
10
11 # Получить первые три буквы фамилии.
12 # Если длина фамилии меньше 3 букв, то
13 # срез вернет всю фамилию целиком.
14 set2 = last[O : 3]
15
16 # Получить последние три буквы фамилии идентификатора.
17 #Если длина идентификатора меньше 3 символов, то
18 # срез вернет весь идентификатор целиком.
19 set3 = idnumЬer[-3 :]
20
21 # Собрать воедино наборы символов.
22 login name = setl + set2 + set3
23
24 # Вернуть имя для входа в систему.
25 return login_name
26
27 # Функция valid_password принимает пароль в
28 # качестве аргумента и возвращает истину либо ложь,
29 # сообщая о его допустимости или недопустимости. Допустимый
30 # пароль должен состоять как минимум из 7 символов,
31 # иметь как минимум один символ в верхнем регистре,
32 # один символ в нижнем регистре и одну цифру.
33
34 def valid_password(password):
35 # Назначить булевым переменным значение False.
36 correct_length = False
37 has_uppercase = False
38 has lowercase = False
39 has digit = False
40
41 # Приступить к валидации.
42 # Начать с проверки длины пароля.

43 if len(password) >= 7:

44 correct length = True
45

Глава В. Подробнее о строковых данных 447

46 # Проанализировать каждый символ и установить
47 # соответствующий флаг, когда
48 # требуемый символ найден.
49 for ch in password:
50 if ch.isupper():
51 has_uppercase True
52 if ch. islower () :
53 has lowercase True
54 if ch.isdigit():
55 has_digit = True
56
57 # Определить, удовлетворены ли все требования.
58 # Если это так, то назначить is_valid значение True.
59 # В противном случае назначить is_valid значение False.
60 if correct_length and has_uppercase and \
61 has lowercase and has_digit:
62 is valid = True
63 else:
64 is valid False
65
66 # Вернуть переменную is valid.
67 return is valid

Программа 8.7 импортирует модуль входа в систему login и демонстрирует функцию
valid_password.

Программа 8.7 (validate_password.py)

1 # Эта программа получает от пользователя пароль
2 # и проверяет его допустимость.

3
4 import login

5 ')
6 def main () :
7 # Получить от пользователя пароль.
8 password = inрut('Введите свой пароль:

10 # Проверить допустимость пароля.
11 while not login.valid_password(password):
12 print ('Этот пароль недопустим.')
13 password input ('Введите свой пароль: ')
14
15 print ('Это допустимый пароль.')

17 # Вызвать главную функцию.
18 main ()

448 Глава 8. Подробнее о строковых данных

Вывод программы (вводимые данные выделены жирным шрифтом )

Введите свой пароль : Ьоzо IEnter l

Этот пароль недопустим .

Введите свой пароль : kangaroo 1Enter 1

Этот пароль недопустим .

Введите свой пароль : Tiger9 IEnter l

Этот пароль недопустим .

Введите свой пароль : Leopard9 1Enter 1

Это допустимый пароль .

В главе 7 вы узнали, как дублировать список при помощи оператора повторения ( * ). Опера­

тор повторения работает и со строковыми значениями. Вот общий формат:

Оператор повторения создает строковое значение, которое содержит п повторных копий
копируемого_ строкового_значения. Вот пример:

my_string = 'w' * 5

После исполнения этой инструкции my_ string будет ссылаться на строковое значение
•wwwww'. Вот еще один пример:

Эта инструкция напечатает:

Программа 8.8 демонстрирует оператор повторения.

Программа 8.8 (гepetitioп_operator.py)

1 # Эта программа демонстрирует оператор повторения.

4 # Напечатать девять строк, увеличивающихся по длине.

5 for count in range(l, 10):
6 print ('Z' * count)

8 # Напечатать девять строк, уменьшающихся по длине.
9 for count in range(8, О, -1):
10 print('Z' * count)

12 # Вызвать главную функцию.

Глава 8. Подробнее о строковых данных 449

Разбиение строкового значения

Строковые значения в Python имеют метод spli t (), который возвращает список, содержа­
щий слова в строковом значении. В программе 8.9 приведен пример.

Программа 8.9 (stгing_split.py)

1 # Эта программа демонстрирует метод split.
2
3 def main () :
4 # Создать строковое значение с несколькими словами.
5 my_string = 'Один два три четыре'

6
7 # Разбить строковое значение.

8 word_list = my_string.split()

10 # Напечатать список слов.
11 print(word_list)
12
13 # Вызвать главную функцию.
14 main ()

По умолчанию метод spli t () в качестве символов-разделителей использует пробелы (т. е.

он возвращает список слов в строковом значении, которые отделены пробелами). Можно

450 Глава 8. Подробнее о строковых данных

задать другой разделитель, передав его в качестве аргумента в метод spl i t (). Например,

предположим, что строковый литерал содержит дату, как показано ниже:

Если требуется извлечь день, месяц и год в качестве элементов списка, то можно вызвать

' / 'метод split (),используя символ в качестве символа-разделителя:

date list = date string.split('/')

После исполнения этой инструкции переменная date_ list будет ссылаться на такой список:

В программе 8.1 О это продемонстрировано.

1 # Эта программа вызывает метод split, используя
2 #символ ' / ' в качестве разделителя.

4 def main () :
5 # Создать строковое значение с датой.

6 date_string = '01/12/2018'
7
8 # Разбить дату.
9 date list date string.split('/')

10
11 # Показать все части даты.

12 print('Дeнь:', date_list[O])
13 print('Mecяц:', date_list[l])
14 print('Гoд:', date_list[2])
15
16 # Вызвать главную функцию.
17 main()

День : 01
Месяц : 12
Год : 2018

8.11. Напишите фрагмент кода с использованием оператора in, который определяет, являет­

ся ли 'd' подстрокой переменной mystring.

8.12. Допустим, что переменная Ьig ссылается на строковое значение. Напишите инструк­

цию, которая преобразует строковое значение, на которое она ссылается, в нижний

регистр и присваивает преобразованный результат переменной little.

8.13. Напишите инструкцию, которая выводит сообщение "Цифра", если строковое значе­

ние, на которое ссылается переменная ch, содержит цифру. В противном случае эта

инструкция должна показать сообщение "Цифр нет".

Глава 8. Подробнее о строковых данных 451

8.14. Что покажет приведенный ниже фрагмент кода?

ch = 'а'
ch2 = ch.upper()
print(ch, ch2)

8.15. Напишите цикл, который запрашивает у пользователя "Желаете повторить программу

или выйти? (П/В)". Цикл должен повторяться до тех пор, пока пользователь не введет
Пили В (в верхнем или нижнем регистре).

8.16. Что покажет приведенный ниже фрагмент кода?

8.17. Напишите цикл, который подсчитывает количество символов в верхнем регистре,

появляющихся в строковом значении, на которое ссылается переменная mystring.

8.18. Допустим, что в программе имеется приведенная ниже инструкция:

days = 'Понедельник Вторник Среда'

Напишите инструкцию, которая разбивает строковое значение, создавая приведенный

8.19. Допустим, что в программе имеется приведенная ниже инструкция:

Напишите инструкцию, которая разбивает строковое значение, создавая приведенный

Вопросы для овто ения

1. Первым индексом в строковом значении является _ _ _ __

г) размер строкового значения минус один.

2. Последним индексом в строковом значении является _ _ _ __

г) размер строкового значения минус один.

452 Глава В. Подробнее о строковых данных

3. Если попытаться использовать индекс, который находится за пределами диапазона стро-
_ _ _ __кового значения, то

а) произойдет исключение ValueError;

б) произойдет исключение IndexError;

в) строковое значение будет стерто, и программа продолжит работу;

г) ничего не произойдет — недопустимый индекс будет проигнорирован.

4. Функция возвращает длину строкового значения.

5. Строковый метод возвращает копию строкового значения, в котором удале-

ны все ведущими пробельные символы.

г) strip_ leading ().

6. Строковый метод _ _ _ _ _ возвращает наименьшую индексную позицию в строковом

значении, где найдена заданная подстрока.

а) first index_ of ();

7. Инструкция _ _ _ _ _ определяет, содержится ли одно строковое значение в другом.

8. Строковый метод возвращает истину, если строковое значение содержит

только буквы и имеет по крайней мере один символ.

9. Строковый метод возвращает истину, если строковое значение содержит

только цифры и имеет по крайней мере один символ.

Глава 8. Подробнее о строковых данных 453

1О. Строковый метод возвращает копию строкового значения, в котором удале-

ны все ведущие и замыкающие пробельные символы.

в) remove_white space ( ) ;
г) rstrip ().

Истина или ложь
1. После создания строкового значения его нельзя изменить.
2. Цикл for можно применять для перебора отдельных символов в строковом значении.
3. Метод isupper () преобразует символы строкового значения в верхний регистр.
4. Оператор повторения(*) работает со строковыми значениями и со списками.
5. Когда вызывается метод spli t () , он разбивает строковое значение на две подстроки.

1. Что покажет приведенный ниже фрагмент кода?

2. Что покажет приведенный ниже фрагмент кода?
mystr = 'абв' * 3

3. Что покажет приведенный ниже фрагмент кода?

mystring = 'абвгдеё'
print(mystring[2:5])

4. Что покажет приведенный ниже фрагмент кода?

numЬers = [1, 2, 3, 4, 5, 6, 7]

5. Что покажет приведенный ниже фрагмент кода?

name = 'джо'
print(name.lower())
print(name.upper())
print(name)

454 Глава 8. Подробнее о строковых данных

1. Допустим, что переменная choice ссылается на строковое значение. Приведенная ниже

инструкция i f определяет, равна ли переменная choice значениям 'д' или 'д':

if choice == 'д' or choice == 'д':

Перепишите эту инструкцию так, чтобы она делала всего одно сравнение и использовала

оператор or. (Подсказка: примените метод upper () либо метод lower () .)

2. Напишите цикл, который подсчитывает количество пробельных символов в строковом

значении, на которое ссылается mystring.

3. Напишите цикл, который подсчитывает количество цифр в строковом значении, на ко­

торое ссылается mystring.

4. Напишите цикл, который подсчитывает количество символов в нижнем регистре в стро­

ковом значении, на которое ссылается mystring.

5. Напишите функцию, которая принимает строковое значение в качестве аргумента и воз­
вращает истину, если аргумент заканчивается подстрокой ' . сот'. В противном случае

функция должна вернуть ложь.

6. Напишите фрагмент кода, делающий копию строкового значения, в котором все вхож­

дения буквы 'т' в нижнем регистре преобразованы в верхний регистр.

7. Напишите функцию, которая принимает строковое значение в качестве аргумента и по­

казывает строковое значение в обратном порядке.

8. Допустим, что переменная mystring ссылается на строковое значение. Напишите инст­
рукцию, которая применяет выражение среза и показывает первые 3 символа в строко­

9. Допустим, что переменная mystring ссылается на строковое значение. Напишите инст­
рукцию, которая применяет выражение среза и показывает последние 3 символа в стро­

1О. Взгляните на приведенную ниже инструкцию:

mystring = 'пирожки>молоко>стряпня>яблочный пирог>мороженое'

Напишите инструкцию, которая разбивает это строковое значение, создавая приведен­
ный ниже список:

1. Инициалы. Напишите программу, которая получает строковое значение, содержащее

имя, отчество и фамилию человека и показывает инициалы. Например, если пользователь
вводит Михаил Иванович Кузнецов, то программа должна вывести М.И.К.

2. Сумма цифр в строке. Напишите программу, которая просит пользователя ввести ряд

однозначных чисел без разделителей. Программа должна вывести на экран сумму всех

однозначных чисел в строковом значении. Например, если пользователь вводит 2514, то
этот метод должен вернуть значение 12, которое является суммой 2, 5, 1 и 4.

3. Принтер дат. Напишите программу, которая считывает от пользователя строковое зна­

чение, содержащее дату в формате дд/мм/гггг. Она должна напечатать дату в формате

12 марта 2018 г.

Глава В. Подробнее о строковых данных 455

4. Конвертер азбуки Морзе. Азбука Морзе представляет собой кодировку, где каждая

буква алфавита, каждая цифра и различные знаки препинания представлены серией точек

и тире. В табл. 8.4 и 8.5 показана часть этой азбуки.

Напишите программу, которая просит пользователя ввести строковое значение и затем
преобразует это строковое значение в кодировку азбукой Морзе.

Таблица 8.4. Азбука Морзе (интернациональная)

Символ Код Символ Код Символ Код Символ Код
пробел пробел —
6 — . G Q —
запятая — ..- 7 — . . R
точка 8 — — -.. н ."
— 9 " s
знак вопроса —- 1 —
..- -.. А — J — т "-
о в
—— с — ". к — u . —
1
2 —- D — L " у —
3 —
4 ..- — — Е м — w — "-
5 . — — " —
. — F N — х — -..
. "-
о — у

Таблица 8.5. Азбука Морзе (русские буквы)

Символ Код Символ Код Символ Код Символ Код
А — и ш
Б " р — щ —-
в — ". й ъ
г — — с . ы — "-
д — к т ь
-" л — .. — э —
Е,Ё м у ю
".- н — ф ..- я ""
ж о —
— -.. п — х — " —
3 — ц
ч "

5. Алфавитный переводчик номера телефона. Многие компании используют телефонные
номера наподобие 555-GET-FOOD, чтобы клиентам было легче запоминать эти номера.

На стандартном телефоне буквам алфавита поставлены в соответствие числа следующим
образом:

456 Глава 8. Подробнее о строковых данных

Напишите программу, которая просит пользователя ввести 10-символьный номер теле­
фона в формате ХХХ-ХХХ-ХХХХ. Приложение должно показать номер телефона, в ко­
тором все буквенные символы в оригинале переведены в их числовой эквивалент.

Например, если пользователь вводит 555-GET-FOOD, то приложение должно вывести
555-438-3663.

6. Среднее количество слов. Среди исходного кода главы 8, а также в подпапке data

"Решений задач по программированию" соответствующей главы вы найдете файл

text.txt. В нем в каждой строке хранится одно предложение. Напишите программу, кото­

рая читает содержимое файла и вычисляет среднее количество слов в расчете на пред­

7. Анализ символов. Среди исходного кода главы 8, а также в подпапке data "Решений за­
дач по программированию" соответствующей главы вы найдете файл text.txt. Напишите

программу, которая читает содержимое файла и определяет:

• количество букв в файле в верхнем регистре;

• количество букв в файле в нижнем регистре;

• количество цифр в файле;

• количество пробельных символов в файле.

8. Корректор предложений. Напишите программу с функцией, принимающей в качестве

аргумента строковое значение и возвращающей его копию, в котором первый символ
каждого предложения написан в верхнем регистре. Например, если аргументом является
"привет! меня зовут джо. а как твое имя?", то эта функция должна вернуть строковое
значение 'Привет! Меня зовут Джо. А как твое имя?'. Программа должна предоста­
вить пользователю возможность ввести строковое значение и затем передать его в функ­
цию. Модифицированное строковое значение должно быть выведено на экран.

9. Гласные и согласные. Напишите программу с функцией, которая в качестве аргумента

принимает строковое значение и возвращает количество содержащихся в нем гласных.

Приложение должно иметь еще одну функцию, которая в качестве аргумента принимает
строковое значение и возвращает количество содержащихся в нем согласных. Приложе­

ние должно предоставить пользователю возможность ввести строковое значение и пока­
зать содержащееся в нем количество гласных и согласных.

Видеозапись "Задача о гласных и согласных" (Т/1е Vowels and Consonaпts ргоЫот)

10. Самый частотный символ. Напишите программу, которая предоставляет пользователю

возможность ввести строковое значение и выводит на экран символ, который появляется
в нем наиболее часто.

11. Разделитель слов. Напишите программу, которая на входе принимает предложение,

в котором все слова написаны без пробелов, но первая буква каждого слова находится
в верхнем регистре. Преобразуйте предложение в строковое значение, в котором слова

Глава В. Подробнее о строковых данных 457

отделены пробелами, и только первое слово начинается с буквы в верхнем регистре. На­
пример, строковое значение "ОстановисьИПочувствуйЗапахРоз" будет преобразовано

в "Остановись и почувствуй запах ро з".

12. Молодежный жаргон. Напишите программу, которая на входе принимает предложение

и преобразует каждое его слово в "молодежный жаргон" . В одной из его версий во время
преобразования слова в молодежный жаргон первая буква удаляется и ставится в конец
слова. Затем в конец слова добавляется слог "ки". Вот пример.

Русский язык: ПРОСПАЛ ПОЧТИ ВСЮ НОЧЬ

Молодежный жаргон: РОСПАЛПКИ ОЧТИПКИ СЮВКИ ОЧЬНКИ

13. Лотерея PowerBall. Для того чтобы сыграть в лотерею PowerBall, покупают билет, в ко­
тором имеется пять чисел от 1 до 69 и число "PowerBall" в диапазоне от 1 до 26. (Эти

числа можно выбрать самому либо дать билетному автомату их выбрать за вас случай­
ным образом.) Затем в заданный день автомат случайным образом отбирает выигрыш­
ный ряд чисел. Если первые пять чисел совпадают с первыми пятью выигрышными чис­

лами в любом порядке, и ваше число PowerBall соответствует выигрышному числу
PowerBall, то вы выигрываете джекпот, который составляет очень крупную сумму денег.

Если ваши числа совпадают лишь с некоторыми выигрышными числами, то вы выигры­

ваете меньшую сумму в зависимости от того, сколько выигрышных номеров совпало .

Среди исходного кода главы 8, а также в подпапке data "Решений задач по программиро­
ванию" соответствующей главы вы найдете файл с именем pbnumbers.txt, содержащий
выигрышные номера PowerBall, которые были отобраны между 3 февраля 201 О и 11 мая
2016 (файл содержит 654 наборов выигрышных чисел). Рис. 8.6 показывает пример пер­

вых нескольких строк содержимого этого файла. Каждая строка в файле содержит набор
из шести чисел, которые были выбраны в заданную дату. Числа отделены пробелом,

и последнее число в каждой строке является числом PowerBall для этого дня. Например,
первая строка в файле показывает числа за 3 февраля 201 О, которые равнялись 17, 22, 36,
37, 52, и число PowerBall, равное 24.

17 22 36 37 52 24
14 22 52 54 59 04
05 08 29 37 38 34
10 14 30 40 51 01
07 08 19 26 36 15
13 27 37 41 54 32
04 17 35 50 57 12

РИС. 8.6. Файл pbnumbers.txt

Напишите одну или несколько программ, которые работают с этим файлом и показы­

• 1О наиболее распространенных чисел, упорядоченных по частоте;
• 1О наименее распространенных чисел, упорядоченных по частоте;

458 Глава В. Подробнее о строковых данных

• 10 наиболее "созревших" чисел (чисел, которые не использовались долгое время),

упорядоченных от наиболее созревших до наименее созревших;

• частоту каждого числа от 1 до 69 и частоту каждого PowerBall числа от 1 до 26.

14. Цены на бензин. Среди исходного кода главы 8, а также в подпапке data "Решений за­
дач по программированию" соответствующей главы, вы найдете файл GasPrices.txt. Этот
файл содержит еженедельные средние цены за галлон бензина в США, начиная 5 апреля
1993 года и заканчивая 26 августа 2013 года. На рис. 8.7 показан пример первых не­

скольких строк данного файла.

sPrkes .ьt — Notep

File Edit Forma ',"! е. Help "

4 — 05-1993:1 . 068 Ln 1, Col
04-12-1993: 1. 079
04 -19 -1993:1 . 079
04-26- 1993:1 . 086
05 -03 -1993:1 . 086
05-10-1993:1 . 097
05 -17 -1993:1 . 106

РИС. 8.7. Файл GasPrices.txt

Каждая строка в файле содержит среднюю цену за галлон бензина в указанный день
и отформатирована следующим образом:

где мм — двухзначный месяц; дц — двухзначный день; гггг — четырехзначный год;

Цена — это средняя цена галлона бензина в указанный день.

В рамках этого задания необходимо написать одну или несколько программ, которые
считывают содержимое данного файла и выполняют приведенные ниже вычисления.

• Средняя цена за год: вычисляет среднюю цену бензина за год для каждого года
в файле. (Данные файла начинаются апрелем 1993 и заканчиваются августом 2013.
Используйте данные, предоставленные за период с 1993 по 2013 годы.)

• Средняя цена за месяц: вычисляет среднюю цену в каждом месяце в файле.

• Наибольшая и наименьшая цены в году: в течение каждого года в файле опреде­

ляет дату и величину самой низкой и самой высокой цены.

• Список цен, упорядоченный по возрастанию: генерирует текстовый файл, в кото­

ром даты и цены отсортирован

в возрастающем порядке.

• Список цен, упорядоченный по увеличению: генерирует текстовый файл, в кото­

ром даты и цены отсортированы в убывающем порядке.

Для выполнения всех этих вычислений можно написать одну программу или несколько

разных программ, одну для каждого вычисления.

1111111(__ КЛЮЧЕВЫЕ ПОЛОЖЕНИЯ

Словарь — это объект-контейнер, который хранит коллекцию данных. Каждый элемент

в словаре имеет две части: ключ и значение. Ключ используется, чтобы установить

местонахождение конкретного значения.

Buдf п Rn сь 'Введещ ев cлnR.:J о' (Jпtmr111r:tron to D1ctronaпes

Когда вы слышите слово "словарь", то, вероятно, представляете толстую книгу, такую как
"Большой толковый словарь", содержащую слова и их определения. Если вы хотите узнать

значение конкретного слова, вы отыскиваете его в словаре и получаете его определение.

В Python словарь — это объект, который хранит коллекцию данных. Каждый хранящийся

в словаре элемент имеет две части: ключ и значение. На практике элементы словаря обычно
называются парами ключ/значение. Когда требуется получить из словаря конкретное значе­
ние, используется ключ, который связан с этим значением. Это подобно процессу поиска

слова в "Большом толковом словаре", где слова являются ключами, а определения — значе­

Например, предположим, что каждый сотрудник компании имеет идентификационный но­

мер, и нам нужно написать программу, которая позволяет отыскивать имя сотрудника путем

ввода идентификационного номера сотрудника. В этом случае можно создать словарь,
в котором каждый элемент содержит идентификационный номер сотрудника в качестве
ключа, и имя этого сотрудника в качестве значения. Если известен идентификационный

номер сотрудника, то можно получить имя этого сотрудника.

Еще одним примером будет программа, которая позволяет вводить имя человека и предос­
тавляет его телефонный номер. Программа могла бы использовать словарь, в котором каж­
дый элемент содержит имя человека в качестве ключа и телефонный номер человека в каче­
стве значения. Если известно имя человека, то можно получить его телефонный номер.

Пары ключ/значение часто называются отображениями, потому что каждому ключу поставлено
в соответствие значение, т. е. каждый ключ как бы отображается на соответствующее ему зна­

460 Глава 9. Словари и множества

Словарь создается путем заключения его элементов в фигурные скобки (

ит из ключа, затем двоеточия, после которого идет значение. Элементы словаря отделяются
запятыми. Приведенная ниже инструкция приводит пример определения словаря:

Эта инструкция создает словарь и присваивает его переменной phonebook (телефонная кни­

га). Словарь содержит приведенные ниже три элемента.

• Первый элемент- 'Крис': '555-1111'. В этом элементе ключом является 'Крис', а зна­

• Второй элемент- 'Кэти': '555-2222'. В этом элементе ключом является 'Кэти', а зна­
-чением '555-2222 '.

• Третий элемент — 'Джоанна' : '555-3333 '. В этом элементе ключом является 'Джоанна',
-а значением '555-3333 '.

В этом примере ключами и значениями являются строковые объекты. Значения в словаре
могут быть объектами любого типа, но ключи должны быть немутирующими объектами.
Например, ключами могут быть строковые значения, целые числа, значения с плавающей
точкой или кортежи. Ключами не могут быть списки либо мутирующие объекты других

Получение значения из словаря

Элементы в словаре не хранятся в каком-то конкретном порядке. Например, взгляните на
приведенный ниже интерактивный сеанс, в котором создается словарь, и его элементы

выводятся на экран:

Обратите внимание, что порядок следования, в котором выводятся элементы, отличается от
порядка, в котором они создавались. Этот пример показывает, что словари не являются
последовательностями, как списки, кортежи и строковые значения. Как результат, невоз­
можно использовать числовой индекс для получения значения по его позиции в словаре.
Вместо этого для получения значения используется ключ.

Для того чтобы получить значение из словаря, просто пишут выражение в приведенном ни­
же общем формате:

имя_ словаря [ключ]

В данном формате имя_ словаря- это переменная, которая ссылается на словарь, ключ­
это применяемый ключ. Если ключ в словаре существует, то выражение возвращает связан­

ное с этим ключом значение. Если ключ не существует, то вызывается исключение KeyError

(ошибка ключа). Приведенный ниже интерактивный сеанс это демонстрирует:

Глава 9. Словари и множества 461

Traceback (most recent call last) :

Рассмотрим этот сеанс подробнее.

+ Строка 1 создает словарь, содержащий имена (в качестве ключей) и телефонные номера

(в качестве значений).

+ В строке 2 выражение phonebook [ 'Крис'] возвращает из словаря phonebook значение,

которое связано с ключом 'Крис'. Это значение показано в строке 3.

+ В строке 4 выражение phonebook [ 'Джоанна' J возвращает из словаря phonebook значение,

которое связано с ключом 'Джоанна'. Это значение показано в строке 5.

+ В строке 6 выражение phonebook [ 'Кэти' J возвращает из словаря phonebook значение,

которое связано с ключом ' Кэти' . Это значение показано в строке 7.

+ В строке 8 вводится выражение phonebook [ 'Кэтрин' ] . Ключ 'Кэтрин' в словаре

phonebook отсутствует, и поэтому вызывается исключение KeyError.

Напомним, что операции сравнения строковых значений регистрочувствительны. Выражение

phonebook [ 'кэти' J не обнаружит в словаре ключа 'Кэти'.

Применение операторов in и not in

для проверки на наличие значения в словаре

Как продемонстрировано ранее, исключение KeyError вызывается при попытке получить из

словаря значение с использованием несуществующего ключа. Для того чтобы предотвратить

это исключение, можно применить оператор in, который определит наличие ключа перед

попыткой его использовать для получения значения. Приведенный ниже интерактивный

сеанс это демонстрирует:

2 >>> if 'Крис' in phonebook: [Enter[
3 print (phonebook [ 'Крис' ] ) [Enter [ ! Enter [
4
5 555-1111
6 >>>

462 Глава 9. Словари и множества

Инструкция i f в строке 2 определяет, имеется ли ключ 'Крис' в словаре phonebook. Если он
имеется, то инструкция в строке 3 показывает значение, которое связано с этим ключом.

Как продемонстрировано в приведенном ниже сеансе, чтобы определить, не существует ли

ключ, можно также применить оператор not in:
1 >>> phonebook = <'Крис': '555-1111', 'Кэти': '555-2222'>[Enter[
2 >>> if 'Джоанна' not in phonebook: [Enter[
3 print ('Джоанна не найдена. ') [Enter [ [Enter [

5 Джоанна не найдена.

Следует иметь в виду, что сравнения строковых значений при помощи операторов in и not in

Добавление элементов в существующий словарь

Словари являются мутирующими объектами. В словарь можно добавлять новые пары
ключ/значение, используя для этого инструкцию присваивания в приведенном ниже общем
формате:

имя_ словаря [ключ] = значение

Здесь имя_ словаря- это переменная, которая ссылается на словарь, ключ- это применяе­
мый ключ. Если ключ уже в словаре существует, то присвоенное ему значение будет замене­
но значением. Если же ключ отсутствует, то он будет добавлен в словарь вместе со связан­
ным с ним значением. Приведенный ниже интерактивный сеанс это демонстрирует:

Рассмотрим этот сеанс.

+ Строка 1 создает словарь, содержащий имена (в качестве ключей) и телефонные номера

(в качестве значений).

+ Инструкция в строке 2 добавляет в словарь phonebook новую пару ключ/значение. По­

скольку ключа 'Джо' в словаре нет, эта инструкция добавляет ключ 'Джо' вместе со свя­

занным с ним значением '555-0123 '.

+ Инструкция в строке 3 изменяет значение, которое было связано с существующим клю­

чом. Поскольку ключ 'Крис' в словаре phonebook уже существует, эта инструкция меняет
связанное с ним значение на '555-4444 '.

+ Строка 4 выводит содержимое словаря phonebook. Результат показан в строке 5.

Глава 9. Словари и множества 463

ПРИМЕЧАНИЕ
В словаре нельзя иметь повторяющиеся ключи. Если присвоить значение существующему ключу,

то новое значение заменит существующее.

Существующую пару ключ/значение можно из словаря удалить при помощи инструкции

del. Вот общий формат:

В данном формате имя_ словаря- это переменная, которая ссылается на словарь, ключ­
это применяемый ключ. После исполнения этой инструкции ключ и связанное с ним значе­
ние будут из словаря удалены. Если ключ не существует, то будет вызвано исключение
KeyError. Приведенный ниже интерактивный сеанс это демонстрирует:

Рассмотрим этот сеанс.

+ Строка 1 создает словарь, а строка 2 показывает его содержимое.
+ Строка 4 удаляет элемент с ключом 'Крис', строка 5 показывает содержимое словаря.

В строке 6 можно увидеть результат — этот элемент в словаре больше не существует.

+ Строка 7 пытается снова удалить элемент с ключом 'Крис '. Поскольку этот элемент

больше не существует, вызывается исключение KeyError.

Для того чтобы предотвратить вызов исключения KeyError, следует применить оператор in,

который определит, имеется ли ключ в словаре, перед попыткой его удалить вместе со свя­
занным с ним значением. Приведенный ниже интерактивный сеанс это демонстрирует:

2 >>> if 'Крис' in phonebook: [Enter[
3 del phonebook [ 'Крис'] [Enter 1 [ Enter [
4
5 >>> phonebook [Ente

464 Глава 9. Словари и множества

Получение количества элементов в словаре

Для того чтобы получить количество элементов в словаре, можно применить встроенную

функцию len. Приведенный ниже интерактивный сеанс это демонстрирует:

Вот краткое описание инструкций в этом сеансе.

+ Строка 1 создает словарь с двумя элементами и присваивает его переменной phonebook.
+ Строка 2 вызывает функцию len, передавая переменную phonebook в качестве аргумента.

Эта функция возвращает значение 2, которое присваивается переменной num_ i tems.

+ Строка 3 передает переменню num items в функцию print. Результат функции выводится

Смешивание типов данных в словаре

Как уже упоминалось ранее, ключи в словаре должны быть немутирующими объектами,

однако связанные с ними значения могут быть объектами любого типа. Например, как про­

демонстрировано в приведенном ниже интерактивном сеансе, значения могут быть списка­

ми. В этом сеансе мы создаем словарь, в котором ключами являются имена студентов, а зна­

-чениями списки экзаменационных оценок.

Рассмотрим этот сеанс подробнее. Инструкция в строках 1

создает словарь и присваивает

его переменной test_scores (экзаменационные оценки). Данный словарь содержит приве­

денные ниже четыре элемента.

+ Первый элемент- 'Кейла': [88, 92, 100). Здесь ключом является 'Кейла ', значени­

ем — список [88, 92, 100).

+ Второй элемент — 'Луис ' : [ 95, 7 4 , 81 J • Здесь ключом является 'Луис ' , значением —

список [95, 74, 81).

+ Третий элемент- 'Софи': [72, 88, 91). Здесь ключом является 'Софи', значением —

список (72, 88, 91).

Глава 9. Словари и множества 465

+ Четвертый элемент- 'Итен': [70, 75, 78]. Здесь ключом является 'Итен', значени-

ем — список (70, 75, 78].

Вот краткое описание остальной части данного сеанса.

+ Строка 5 выводит содержимое словаря, как показано в строках 6-7.
+ Строка 8 получает значение, которое связано с ключом 'Софи'. Это значение выводится

+ Строка 1О получает значение, которое связано с ключом 'Кейла' и присваивает его пере­

менной kayla_ scores. После исполнения этой инструкции переменная kayla_ scores ссы­

лается на список (88, 92, 100].

+ Строка 11 передает переменную kayla scores в функцию print. Вывод этой функции

показан в строке 12.

Значения, хранящиеся в одном словаре, могут иметь разные типы. Например, значение не­

которого элемента может быть строковым объектом, значение другого элемента — списком,
а значение еще одного элемента — целым числом. Ключи тоже могут иметь разные типы, но

они должны оставаться немутирующими. Приведенный ниже интерактивный сеанс демон­
стрирует, каким образом разные типы могут быть перемешаны в словаре:

Инструкция в строке 1 создает словарь и присваивает его переменной mixed up (смесь). Этот

словарь содержит приведенные ниже элементы.

+ Первый элемент — 'абв' : 1 '. В этом элементе ключом является строковый литерал

'абв', значением — целое число 1.

+ Второй элемент — 999: 'тада тада'. В этом элементе ключом является целое число 999,

-значением строковое значение 'тада тада '.

+ Третий элемент — (3, 6, 9): (3, 6, 9]. В этом элементе ключом является кортеж

(3, 6, -9), значением список [3, 6, 9].

Приведенный ниже интерактивный сеанс демонстрирует более практический пример. Он
создает словарь, который содержит различные порции данных о сотруднике:

Инструкция в строке 1 создает словарь и присваивает его переменной employee. Данный

словарь содержит приведенные ниже элементы.

+ Первый элемент — 'фио' : 'Кевин Смит'. Здесь ключом является строковый литерал

-'фио ', значением строковое значение 'Кевин Смит'.

+ Второй элемент- 'ид' :12345. В этом элементе ключом является строковый литерал

-•ид •,значением целое число 12345.

+ Третий элемент — 'ставка': 25. 75. Здесь ключом является строковый литерал 'ставка',

значением — число с плавающей точкой 25. 75.

466 Глава 9. Словари и множества

Создание пустого словаря

Иногда требуется создать пустой словарь и добавлять в него элементы по мере выполнения
программы. Для создания пустого словаря используются пустые фигурные скобки:

Инструкция в строке создает пустой словарь и присваивает его переменной phonebook.

Строки 2-4 добавляют пары ключ/значение в словарь, а инструкция в строке 5 выводит

Для создания пустого словаря также можно воспользоваться встроенным методом dict () :
phonebook = dict()

После исполнения этой инструкции переменная phonebook будет ссылаться на пустой сло­

Применение цикла for

для последовательного обхода словаря

Для перебора всех ключей словаря применяется цикл for:
for переменная in словарь:

В данном формате переменная- это имя переменной, словарь — имя словаря. Этот цикл

выполняет одну итерацию для каждого элемента в словаре. Во время каждой итерации цик­
ла переменной присваивается ключ. Приведенный ниже интерактивный сеанс это демонст­

6
7
8 Крис
9 Кэти

10 Джоанна
11 >>> for key in phonebook: ]Enter]
12 print(key, phonebook [key]) ]Enter] ]Enter]
13
14

Глава 9. Словари и множества 467

15 Крис 555-1111

16 Кэти 555-2222

17 Джоанна 555-3333

Вот краткое описание инструкций в данном сеансе.

+ Строки 1-3 создают словарь с тремя элементами и присваивают его переменной

+ Строки 4-5 содержат цикл for, который выполняет одну итерацию для каждого элемента

словаря phonebook. Во время каждой итерации цикла переменной key присваивается

ключ. Строка 5 печатает значение переменной key. Строки 8-10 показывают результат

+ Строки 11-12 содержат еще один цикл for, который делает одну итерацию для каждого

элемента словаря phonebook, присваивая ключ переменной key. Строка 15 печатает пере­
менную key и затем значение, которое связано с этим ключом. Строки 15-17 показывают

результат работы цикла.

Несколько словарных методов

Объекты-словари имеют ряд методов. В этом разделе мы рассмотрим несколько наиболее

полезных из них, которые приведены в табл. 9.1.

Таблица 9.1. Несколько словарных методов

clear () Очищает содержимое словаря
get ()
Получает значение, связанное с заданным ключом. Если ключ не найден, то этот метод
items () не вызывает исключение. Вместо этого он возвращает значение по умолчанию

keys () Возвращает все ключи в словаре и связанные с ними значения в виде последовательности
кортежей
рор()
Возвращает все ключи в словаре в виде последовательности кортежей
popitem()
Возвращает из словаря значение, связанное с заданным ключом и удаляет эту пару
values () ключ/значение. Если ключ не найден, то этот метод возвращает значение по умолчанию

Возвращает произвольно выбранную из словаря пару ключ/значение в виде кортежа
и удаляет эту пару ключ/значение из словаря

Возвращает все значения из словаря в виде последовательности кортежей

Метод clear () удаляет все элементы в словаре, оставляя словарь пустым. Общий формат

Приведенный ниже интерактивный сеанс демонстрирует работу этого метода:

468 Глава 9. Словари и множества

Обратите внимание, что после исполнения инструкции в строке 4 словарь phonebook больше

элементов не содержит.

Для получения значения из словаря в качестве альтернативы оператору [J можно восполь­

зоваться методом get (J • Он не вызывает исключение, если заданный ключ не найден. Вот

общий формат этого метода:

словарь.gеt (ключ, значение_по_умолчанию)

В данном формате словарь — это имя словаря, ключ- это искомый в словаре ключ, значе­
ние_по_умолчанию — значение, которое возвращается, если ключ не найден. Когда этот метод
вызывается, он возвращает значение, которое связано с заданным ключом. Если заданный
ключ в словаре не найден, то этот метод возвращает значение_по_умолчанию. Приведенный
ниже интерактивный сеанс демонстрирует работу этого метода:

Рассмотрим этот сеанс.

+ Инструкция в строке 2 ищет в словаре phonebook ключ 'Кэти'. Этот ключ найден, поэто­

му возвращается связанное с ним значение, которое затем присваивается переменной

+ Строка 3 передает переменную value в функцию print. Результат функции выводится

+ Инструкция в строке 5 ищет в словаре phonebook ключ 'Энди'. Этот ключ не найден,

поэтому переменной value присваивается строковый литерал 'Запись не найдена'.

+ Строка 6 передает переменную value в функцию print. Результат функции выводится

Метод i tems () возвращает все ключи словаря и связанные с ними значения. Они возвраща­

ются в виде последовательности особого типа, которая называется словарным представле­
нием. Каждый элемент в словарном представлении является кортежем, и каждый кортеж
содержит ключ и связанное с ним значение. Например, предположим, что мы создали при­
веденный ниже словарь:

Глава 9. Словари и множества 469

Если вызвать метод phonebook. i terns (), то он вернет приведенную ниже последователь­

Обратие внимание на следующие моменты:

+ первым элементом в последовательности является кортеж ( 'Крис', '555-1111');
+ вторым элементом в последовательности является кортеж ('Кэти', '555-2222');
+ третьим элементом в последовательности является кортеж ('Джоанна', '555-3333').

Для того чтобы выполнить перебор кортежей в последовательности, можно применить цикл

1 >>> phonebook = <'Крис': '555-1111', IEnterl
2 'Кэти' : '555-2222', [Enter [
3 'Джоанна': '555-3333'> IEnter[
4 >>> for key, value in phonebook.iterns(): IEnterl
5 print(key, value) [Enter[ [Enter[
6

В Крис 555-1111
9 Кэти 555-2222
10 Джоанна 555-3333
11 >»

Вот краткое описание инструкций в этом сеансе.

+ Строки 1-3 создают словарь с тремя элементами и присваивают его переменной

+ Цикл for в строках 4-5 вызывает метод phonebook. i terns (), который возвращает после­

довательность кортежей, содержащих пары ключ/значение словаря. Данный цикл выпол­
няет одну итерацию для каждого кортежа в последовательности. Во время каждой итера­

ции цикла значения кортежа присваиваются переменным key и value. Строка 5 печатает
значение переменной key и затем значение переменной value. Строки 8-10 показывают

результат работы цикла.

Метод keys () возвращает все ключи словаря в виде словарного представления, т. е. особого

типа последовательности. Каждый элемент в словарном представлении является ключом
словаря. Например, предположим, что мы создали такой словарь:

Если вызвать метод phonebook. keys (), то он вернет приведенную ниже последовательность:

Приведенный ниже интерактивный сеанс показывает, каким образом можно применить цикл

for для обхода последовательности, которая возвращается из метода keys () :

470 Глава 9. Словари и множества

4 >>> for key in phonebook.keys(): 1Enter1
5 print (key) 1Enter 1 1Enter 1

6
7
8 Крис
9 Кэти

Метод рор () возвращает значение, связанное с заданным ключом, и удаляет эту пару

ключ/значение из словаря. Если ключ не найден, то метод возвращает значение по умолча­
нию. Вот общий формат этого метода:

словарь.рор (ключ, значение_по_умолчанию)

В данном формате словарь — это имя словаря, ключ- это искомый в словаре ключ, значе­
ние_по_умолчанию- значение, которое возвращается, если ключ не найден. Когда этот метод

вызывается, он возвращает значение, которое связано с заданным ключом, и удаляет эту пару

ключ/значение из словаря. Если заданный ключ в словаре не найден, то метод возвращает
значение_по_умолчанию. Приведенный ниже интерактивный сеанс это демонстрирует:

Вот краткое описание инструкций в этом сеансе.

+ Строки 1-3 создают словарь с тремя элементами и присваивают его переменной

+ Строка 4 вызывает метод phonebook. рор (), передавая 'Крис' в качестве ключа поиска.

Связанное с ключом ' Крис ' значение возвращается и присваивается переменной

phone_ num. Пара ключ/значение, содержащая ключ 'Крис ', удаляется из словаря.

+ Строка 5 показывает значение, присвоенное переменной phone_ num. Результат выводится

в строке 6. Обратите внимание, что он представляет собой значение, которое было связа­

но С ключом 'Крис'.

+ Строка 7 показывает содержимое словаря phonebook. Результат показан в строке 8. Обра­

тите внимание, что пара ключ/значение, которая содержала ключ ' Крис ' , больше в сло­

варе не существует.

Глава 9. Словари и множества 471

+ Строка 9 вызывает метод phonebook. рор () , передавая 'Энди' в качестве ключа поиска.

Данный ключ не найден, поэтому переменной phone_ nurn присваивается строковый лите­

рал 'Запись не найдена'.

+ Строка 1О показывает значение, присвоенное переменной phone_ nurn. Вывод показан

+ Строка 12 показывает содержимое словаря phonebook. Результат показан в строке 13.

Метод popi tem () возвращает произвольно выбранную пару ключ/значение и удаляет эту

пару из словаря. Пара ключ/значение возвращается в виде кортежа. Вот общий формат этого

словарь. popi tem ()

Для того чтобы присвоить возвращаемый ключ и значение отдельным переменным, инст­
рукция присваивания применяется в приведенном ниже общем формате:

k, v = словарь.рорitеm()

Этот тип присваивания называется кратным присваиванием, потому что значения присваи­

ваются сразу нескольким переменным. В приведенном выше общем формате k и v — это

переменные. После исполнения этой инструкции переменной k присваивается произвольно
выбранный из словаря ключ, а переменной v — значение, связанное с этим ключом. Пара
ключ/значение удаляется из словаря.

Приведенный ниже интерактивный сеанс это демонстрирует:

4 >>> phonebook IEnterl

6 >>> key, value = phonebook.popitem() IEnterl

7 >>> print(key, value) IEnterl

9 >>> phonebook IEnterl

Вот краткое описание инструкций в этом сеансе.

+ Строки 1-3 создают словарь с тремя элементами и присваивают его переменной

+ Строка 4 выводит содержимое словаря, которое показано в строке 5.
+ Строка 6 вызывает метод phonebook. popi tem () . Возвращаемые из этого метода ключ и

значение присваиваются переменным key и value. Пара ключ/значение удаляется из сло­

+ Строка 7 выводит значения, присвоенные переменным key и value. Результат показан

+ Строка 9 выводит содержимое словаря. Результат показан в строке 10. Обратите внима­

ние, что в строке 6 возвращенная из метода popi tem () пара ключ/значение была удалена.

472 Глава 9. Словари и множества

Следует иметь в виду, что если метод popitem () вызывается с пустым словарем, то он вызы­
вает исключение KeyError.

Метод values () возвращает все значения словаря (без своих ключей) в виде словарного

представления, т. е. особого типа последовательности. Каждый элемент в словарном пред­
ставлении является значением из словаря. Например, предположим, что мы создали приве­
денный ниже словарь:

Если вызвать метод phonebook. values (),то он вернет такую последовательность:

[ '555-1111', 1 555-2222', 1 555-3333 1 ]

Приведенный ниже интерактивный сеанс показывает, каким образом можно применить цикл

for для обхода последовательности, которая возвращается из метода values ():
1 >>> phonebook = ('Крис' :'555-1111', [EnterJ
2 'Кэти':'555-2222', [Enter[
3 'Джоанна':'555-3333') [Enter[
4 >>> for val in phonebook.values(): rEnter[
5 print(val) [Ente!] [Enter[

8 555-1111
9 555-3333
10 555-2222
11 >>>

Применение словаря для имитации карточной колоды

В некоторых играх, связанных с игральными картами, картам присваиваются числовые зна­
чения. Например в игре блек-джек картам даются числовые значения:

+ числовым картам присваивается значение, которое на них напечатано. Например, двойка

пик равняется 2, а пятерка бубей равняется 5;

+ валетам, дамам и королям назначается значение 1О;
+ тузам назначается 1 либо 11 в зависимости от выбора игрока.

В этой рубрике мы рассмотрим программу, которая применяет словарь для имитирования
стандартной колоды игральных карт, где картам присваиваются числовые значения, подоб­
ные тем, которые используются в игре блек-джек. (В этой программе мы присваиваем всем

тузам значение 1.) В парах ключ/значение достоинство карты используется в качестве клю­
ча, а числовое значение карты — в качестве значения. Например, пара ключ/значение для

дамы червей будет такой:

'Дама червей' : 1 О

Глава 9. Словари и множества 473

А пара ключ/значение для восьмерки бубей будет такой:

Программа предлагает пользователю ввести количество карт, которые нужно раздать, и
произвольным образом раздает на руки это количество карт из колоды. Затем выводятся

достоинства розданных карт, а также сумма их достоинств. В программе 9.1 приведен соот­

ветствующий код. Программа разделена на три функции: main (главная), create_deck (соз­
дать колоду) и deal_ cards (раздать карты). Вместо того чтобы представлять всю программу
целиком, давайте сначала рассмотрим главную функцию main.

Программа 9.1 (card_dealer.py). Главная функция

1 # Эта программа применяет словарь в качестве колоды карт.
2
3 def main () :
4 # Создать колоду карт.
5 deck = create_deck()
6
7 # Получить количество карт для раздачи.
8 num cards = int(input('Cкoлькo карт раздать? '))
9
10 # Раздать карты.
11 deal cards(deck, num_cards)
12

Строка 5 вызывает функцию create_deck. Она создает словарь, содержащий пары

ключ/значение для колоды карт, и возвращает ссылку на словарь. Ссылка присваивается

переменной deck (колода).

Строка 8 предлагает пользователю ввести количество карт для раздачи. Введенное значение

конвертируется в целочисленный тип int и присваивается переменной num_ cards.

Строка 11 вызывает функцию deal_ cards, передавая ей в качестве аргументов переменные

deck и num_ cards. Функция deal_ cards раздает заданное количество карт из колоды.

Далее идет функция create deck.

Программа 9.1 (продолжение). Функция create_ deck

13 # Функция create_deck возвращает словарь,
14 # представляющий колоду карт.
15 def create_deck():
16 # Создать словарь, в котором каждая карта и ее значение
17 # хранятся в виде пар ключ/значение.
18 deck = <'Туз пик' :1, '2 пик' :2, '3 пик' :3,
19 '4 пик' :4, '5 пик' :5, '6 пик' :6,
20 '7 пик':7, '8 пик':8, '9 пик':9,
21 ' 1О пик ' : 1 О, 'Валет пик' : 1 О,
22 'Дама пик' :10, 'Король пик': 10,
23

474 Глава 9. Словари и множества

24 ' Туз червей' : 1, ' 2 червей' : 2, ' 3 червей' : 3,
25 '4 червей' :4, '5 червей' :5, '6 червей' :6,
26 ' 7 червей' : 7, ' 8 червей' : 8, ' 9 червей' : 9,
27 '10 червей': 10, 'Валет червей': 10,
28 'Дама червей' :10, 'Король червей': 10,
29
30 ' Туз треф' : 1, ' 2 треф ' : 2, ' 3 треф' : 3,
31 ' 4 треф' : 4, ' 5 треф' : 5, ' 6 треф' : 6,
32 ' 7 треф' : 7, ' 8 треф' : 8, ' 9 треф' : 9,
33 '10 треф' :10, 'Валет треф' :10,
34 'Дама треф ' : 1 О, ' Король треф' : 1 О,
35
36 ' Туз бубей' : 1, ' 2 бубей' : 2, ' 3 бубей' : 3,
37 ' 4 бубей' : 4, ' 5 бубей' : 5, ' 6 бубей' : 6,
38 ' 7 бубей' : 7, ' 8 бубей' : 8, ' 9 бубей' : 9,
39 ' 1 О бубей' : 1 О, 'Валет бубей' : 1 О,
40 'Дама бубей' : 1 О, ' Король бубей' : 1 О )
41
42 # Вернуть колоду.
43 return deck
44

Программный код в строках 18-40 создает словарь с парами ключ/значение, представляю­
щими карты стандартной игральной колоды. (Пустые строки 22, 29 и 35 вставлены, чтобы

было легче читать программный код.)

Строка 43 возвращает ссылку на словарь.

Далее идет функция deal cards.

Программа 9.1 (окончание). Функция deal_cards

45 # Функция deal cards раздает заданное количество карт
46 # ИЗ КОЛОДЫ.
47
48 def deal_cards(deck, numЬer):
49 # Инициализировать накопитель для количества карт на руках.
50 hand value = О
51
52 # Убедиться, что количество карт для раздачи
53 # не больше количества карт в колоде.

54 if numЬer > len(deck):
55 numЬer = len(deck)
56
57 # Раздать карты и накопить их значения.

58 for count in range(numЬer):
59 card, value = deck.popitem()

Глава 9. Словари и множества 475

60 print(card)
61 hand value += value
62
63 # Показать величину карт на руках.
64 print ('Величина карт на руках: ', hand_value)
65
66 # Вызвать главную функцию.
67 main ()

Функция deal_ cards принимает два аргумента: количество карт для раздачи и колоду, из
которой они раздаются. Строка 50 инициализирует накапливающую переменную
hand_value (сумма достоинств карт на руках) значением О. Инструкция i f в строке 54 опре­

деляет, не превышает ли количество карт, подлежащих раздаче, количество карт в колоде.

Если это так, то строка 55 задает количество раздаваемых карт равным количеству карт

Цикл for, который начинается в строке 58, выполняет одну итерацию для каждой раздавае­
мой карты. Внутри цикла инструкция в строке 59 вызывает метод popi tem (), который воз­
вращает из словаря deck произвольную пару ключ/значение и удаляет эту пару из словаря 1 •
Ключ присваивается переменной card, а значение- переменной value. Строка 60 показы­
вает достоинство карты, строка 61 прибавляет значение карты в накопитель hand_ value.

После завершения цикла строка 64 показывает сумму достоинств комбинации карт на руках.

Вывод программы (вводимые данные выделены жирным шрифтом)

Сколько карт раздать? 5 I Enter l
8 червей

5 бубей
5 червей

10 пик
Величина карт на руках: 38

В ЦЕНТРЕ ВНИМАНИЯ

Хранение имен и дней рождения в словаре

В этой рубрике мы рассмотрим программу, которая хранит в словаре имена ваших друзей
и дни их рождения. Каждая запись в словаре использует имя друга в качестве ключа, а его
день рождения в качестве значения. Эту программу можно использовать для поиска дней
рождения друзей по вводимому имени.

1 Для произвольного отбора элементов без удаления их из словаря следует использовать метод random (). —

476 Глава 9. Словари и множества

Программа показывает меню, которое позволяет пользователю выбрать один из приведен­
ных ниже вариантов действий:

1. Отыскать день рождения.

2. Добавить новый день рождения.

3. Изменить день рождения.

4. Удалить день рождения.

5. Выйти из программы.

Программа первоначально начинает работу с пустого словаря, поэтому вам нужно выбрать

из меню пункт 2, чтобы добавить новую запись. Когда вы добавите несколько записей, мож­
но выбрать пункт 1, чтобы отыскать день рождения определенного человека, пункт 3, чтобы
изменить существующий день рождения в словаре, пункт 4, чтобы удалить день рождения
из словаря, или пункт 5, чтобы выйти из программы.

В программе 9.2 приведен соответствующий код. Программа разделена на шесть функций:

main (главная), get_menu_ choice (получить пункт меню), look_up (отыскать), add (добавить),
change (изменить) и delete (удалить). Вместо того чтобы приводить всю программу цели­
ком, давайте сначала исследуем глобальные константы и главную функцию main.

Программа 9.2 (blrthdays.py). Главная функция

1 # Эта программа применяет словарь для хранения

2 # имен и дней рождения друзей.

4 # Глобальные константы для пунктов меню

11 # Главная функция.

13 # Создать пустой словарь.

16 # Инициализировать переменную для выбора пользователя.

19 while choice != QUIT:

#20 Получить выбранный пользователем пункт меню.

21 choice = get_menu_choice()

23 # Обработать выбранный вариант действий.

24 if choice == LOOK UP:

26 elif choice == ADD:

27 add (Ьirthdays)

Глава 9. Словари и множества 477

28 elif choice == CНANGE:
29 change(birthdays)
30 elif choice == DELETE:
31 delete(birthdays)
32

Глобальные константы, объявленные в строках 5-9, используются для проверки выбранного
пользователем пункта меню. В главной функции строка 14 создает пустой словарь, на кото­
рый ссылается переменная Ьirthdays. Строка 17 инициализирует переменную choice значе­

нием О. Эта переменная содержит выбранный пользователем пункт меню.

Цикл while, который начинается в строке 19, повторяется до тех пор, пока пользователь не
примет решение выйти из программы. Внутри цикла строка 21 вызывает функцию

get_ menu_ choice. Функция get_ menu_ choice выводит меню и возвращает сделанный пользо­
вателем выбор. Возвращенное значение присваивается переменной choice.

Инструкция if-elif в строках 24-31 обрабатывает выбранный пользователем пункт меню.
Если пользователь выбирает пункт 1, то строка 25 вызывает функцию look_ up. Если пользо­
ватель выбирает пункт 2, то строка 27 вызывает функцию add. Если пользователь выбирает
пункт 3, то строка 29 вызывает функцию change. Если пользователь выбирает пункт 4, то
строка 31 вызывает функцию delete.

Далее идет функция get_menu_choice.

Программа 9.2 (продолжение). Функция qet_menu_choice

33 # Функция get_menu_choice выводит меню и получает
34 # проверенный на допустимость выбранный пользователем пункт.
35 def get_menu_choice():
36 print ()
37 print ('Друзья и их дни рождения')
38 print('———————— 1 )
39 print('l. Найти день рождения')
40 print ( '2. Добавить новый день рождения')
41 print('3. Изменить день рождения')
42 print('4. Удалить день рождения')
43 print ( '5. Выйти из программы')
44 print()
45
46 # Получить выбранный пользователем пункт.
4 7 choice = int (input ( 'Введите выбранный пункт: ' ) )
48
49 # Проверить выбранный пункт на допустимость.
50 while choice < LOOK UP or choice > QUIT:
51 choice = int(input('Bвeдитe выбранный пункт: '))
52
53 # Вернуть выбранный пользователем пункт.
54 return choice
55

Что покажет приведенный ниже фрагмент кода mystr да mystr mystr нет mystr mystr да print mystr

В JavaScript значения строк , а это значит, что они не могут быть изменены после создания. Например, следующий код: не может изменить значение myStr на «Job», потому что содержимое myStr не может быть изменено. Обратите внимание, что это не означает, что значение переменной myStr нельзя изменить. Нельзя изменить именно отдельные символы строки. Но можно изменить в целом значение переменной myStr , если присвоить ей новое значение, например:

Исправьте присвоение значения переменной myStr , чтобы она содержала строковое значение Hello World , используя подход, показанный в приведенном выше примере.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *