/
Tags: языки программирования программирование
ISBN: 978-5-04-214684-8
Text
Юлия Камалова
ПРОГРАММИРОВАНИЕ
ИPYTHON
С НУЛЯ
Базовые концепции
• Синтаксис языка и ООП
• Структуры данных
• Основные алгоритмы
БОМБОРА
ИЗДАТЕЛЬСТВО
Юлия Камалова
ПРОГРАММИРОВАНИЕ
«PYTHON
С НУЛЯ
РОССИЙСКИЙ
КОМПЬЮТЕРНЫЙ
БЕСТСЕЛЛЕР
Ь БОМБОРА
ИЗДАТЕЛЬСТВО
Москва
УДК 004.43
ББК 32.973-018.2
К18
Качалова, Юлия Борисовна.
К18 Программирование на Python с нуля / Юлия Камалова —
Москва: Эксмо. 2026. —448 с. — (Российский компьютерный
бестселлер).
ISBN 978-5-04-214684-8
Книга «Программирование на Python с нуля» — это полное руко-
водство для начинающих, студентов и всех, кто хочег освоить Python.
Вы познакомитесь с основами языка, научитесь работать в IPython,
Jupyter Notebook, Google Colab и Anaconda, разберетесь с ветвлениями,
циклами, типами и структурами данных и объектно ориентированным
программированием. Особое внимание уделено инженерии данных,
работе с API и базами данных, визуализации (Matplot lib, Seaborn),
а также применению Python в науке и машинном обучении (NumPj,
Pandas, scikit-learn). Книга содержит множество примеров и советы по
развитию карьеры.
УДК 004.43
ББК 32.973-018.2
ISBN 978-5-04-214684-8
© Камалова Ю.Б., текст, иллюстрации, 2026
© Оформление. ООО «Имательство «Эксмо», 2026
Оглавление
Об авторе ........................................................ 9
Введение ........................................................ 10
Глава 1. Введение в программирование на языке Python ......... 14
Цели, задачи и основные понятия раздела ...................... 14
Более подробно о программном обеспечении ..................... 16
iPytbon .................................................. 16
Jupyter Notebook .......................................... 17
Google Colab .............................................. 18
Anaconda .................................................. 19
PyCharm ................................................... 20
Интегрированная среда разработки (IDE) .................... 20
Глава 2. Интерактивная среда i Python ........................... 22
Что такое Python? ............................................ 22
Как описать язык программирования ......................... 22
История Python ............................................... 24
Рождение языка ............................................ 24
Развитие языка ............................................ 25
Лицензия ..................................................... 26
Свободное распространение ................................. 27
Python Software Foundation License ....................... 27
Портируемость .............................................. 27
11ортируемость в контексте Python ....................... 28
Примеры портируемости ..................................... 28
Режим работы Python .......................................... 28
Стандартный режим ......................................... 28
Интерактивный режим ....................................... 29
Эффективность в Python ....................................... 30
Выполнение............................................... 30
Разработка ................................................ 31
Тестирование .............................................. 32
Библиотеки Python ........................................... 32
Стандартные библиотеки .................................... 32
Сторонние библиотеки ...................................... 33
Примеры различий .......................................... 34
Пакетный менеджер PyPI и pip .............................. 36
Сообщество и документация ............................. 36
Модульность и повторное использование кода ................ 36
Примеры применения библиотек .............................. 37
Концепция Python Zen ........................................ 37
Выводы ...................................................... 38
Глава 3. Управляющие конструкции в Python: ветвления, циклы,
исключения ..................................................... 41
Алгоритм создания первой программы в Google Colah ......... 41
Ветвления в Python .......................................... 46
Циклы в Python .............................................. 55
Цикл for .................................................. 55
Цикл while ................................................ 57
Операторы break и continue ................................ 59
Функция enumerateO ........................................ 63
Функция zip() ........................................ 64
Сочетание for с enumerateO и zip() ........................ 66
Обработка исключений ...................................... 69
Выводы ...................................................... 71
1 лава 4. Основные синтаксические конструкции Python .......... 74
Арифметические операторы +,-,/,//,%,** ...................... 74
Основные правила приоритета операторов в Python
(от высшего к низшему) .................................... 78
Операторы присваивания: =, — +=,-=,*=,/=,//=,%=,**=.......... 82
Правила и рекомендации по наименованию переменных ........... 87
Типы данных: int, float и str ............................... 87
Правила определения типа переменной в Python .............. 88
Определение типа переменной .............................. 88
Особенности и нюансы типов ................................ 89
Преобразование между типами............................... 89
Важные нюансы ............................................. 90
Строковые операции .......................................... 90
Более сложные сценарии ...................................... 92
Операторы сравнения ....................................... 93
Основные операторы сравнения .............................. 93
Типы данных логических выражений .......................... 96
Проверка четности числа в Python .......................... 96
Оператор членства in ...................................... 99
Методы lower() и upper() ................................... 101
Логические операторы and и or ................................. 102
Оператор and ............................................. 103
Оператор or ................................................ 104
Использование логических операторов в условиях ............. 104
Дополнения к логическим операторам and и or ................ 105
Использование в списковых выражениях (list comprehensions) . 106
Практический пример с пользовательским вводом .............. 108
Циклы ......................................................... ПО
Циклы со счетчиком ......................................... 110
Цикл for ................................................... 110
Цикл for ................................................... Ill
Конструкция range() ........................................ 112
Операторы break и continue в цикле for...................... 115
Цикл while ................................................. 118
Выводы ...................................................... 121
Глава 5. Структуры данных в Python ............................... 124
Строки ........................................................ 124
Индексы и срезы строк ...................................... 129
Изменяемость строк ......................................... 133
Длина строки ............................................... 134
Словари .................................................... 135
Словари как инструмент для хранения данных ................. 149
Проход по словарю в цикле .................................. 150
Изменение словаря во время итерации ........................ 153
Вложенные словари в Python ................................. 154
Кортежи ....................................................... 160
Характеристики кортежей .................................... 160
Создание кортежа из одного элемента .. ..... ... ... ... 162
Доступ к элементам кортежа ................................. 163
Списки ........................................................ 164
Создание списков ........................................... 165
Доступ к элементам списка................................... 165
Основные операции со списками .............................. 168
Функция 1еп() в списках .................................. 172
Функция type() в списках ................................. 179
Индексы и срезы в списках ................................ 183
Методы работы со списками ................................ 184
Выводы ..................................................... 190
Глава 6. Инженерия данных: манипуляции с файлами и каталогами... 195
Текстовые файлы ............................................ 195
Фундаментальные аспекты работы с файлами ............. 195
Чтение текстового файла .................................. 196
Обработка исключительных ситуаций при работе с файлами ... 201
Манипуляции со структурированными данными ............ .. 202
Чтение и запись данных в формате JSON .................... 210
Работа с XML-документами ................................. 216
Обработка медиафайлов ...................................... 223
Работа с изображениями ................................... 223
Работа со звуковыми файлами ................................ 234
Установка необходимых библиотек .......................... 235
Взаимодействие с веб-API ................................... 24)
Библиотека requests для HTTP-запросов .................... 241
Основная терминология .................................... 241
Библиотеки для работы с веб-АР1 .......................... 242
Практические примеры автоматизации ........................ 249
Выводы ..................................................... 252
Глава 7. Основы объектно ориентированного программирования
в Python ..................................................... 257
Основные принципы ООП ...................................... 257
Инкапсуляция ............................................. 257
Защита данных и свойства статуса ......................... 258
Свойства и методы ........................................ 260
Синглтоны и управляемый доступ ........................... 262
Защита состояний через свойства .......................... 264
Уровни доступа ........................................... 267
Наследование ............................................... 269
Логика наследования ...................................... 269
Множественное наследование ............................... 270
Суперклассы и метод super() .............................. 272
Полиморфное наследование и изменение поведения ........... 274
Класс-обертка (wrapper class) ............................ 277
Полиморфизм ................................................ 279
Паттерн «Стратегия» ..................................... 284
Интерфейсы через duck typing ............................ 286
Обобщенные функции и классы .......................... 288
Абстракция ................................................. 290
Классы и объекты: строительные блоки ООП ................. 302
Инкапсуляция, наследование и полиморфизм
(дополнительные примеры) ................................... 309
Инкапсуляция ............................................ 309
Наследование ............................................ 313
Полиморфизм ............................................. 316
Обработка исключений и итераторы ........................... 322
Итераторы ............................................... 322
Декораторы и метаклассы .................................... 323
Декораторы классов ...................................... 323
Метаклассы .............................................. 324
Паттерны проектирования .................................... 325
Singleton (Одиночка) .................................... 325
Фабричный метод ......................................... 325
Наблюдатель ............................................. 326
Выводы ..................................................... 327
Глава 8. Работа с базами данных в Python ...................... 331
Подключение к базам данных и выполнение запросов ........... 331
ORM и SQI.Alchemy: абстракция вместо SQL ................... 332
Обработка результатов запросов и отображение данных ........ 334
Преобразование результатов в словари с использованием
SQLite .................................................. 334
Использование библиотеки Pandas для анализа данных ...... 336
Исторический экскурс: PostgreSQL vs NoSQL .................. 337
Реляционные базы данных (PostgreSQL) .................... 337
NoSQL-базы данных ....................................... 337
Введение в NoSQL: MongoDB на примере ....................... 338
Выводы ..................................................... 339
Глава 9. Графическое программирование........................ 341
Разработка графических приложений .......................... 341
Альтернативные подходы в Google Colab ................... 341
Визуализация данных ........................................ 343
Matplotlib .............................................. 343
Seaborn — расширенные возможности визуализации ............... 363
Выводы ....................................................... 381
Глава 10. Применение Python в научных вычислениях,
анализе данных и машинном обучении .............................. 384
Научные вычисления и анализ данных ........................... 384
Библиотека NumPy: основы работы с многомерными массивами .... 384
Библиотека Pandas инструменты для анализа табличных
данных .................................................... 401
Машинное обучение и искусственный интеллект .................. 419
Библиотека scikit-learn: от предобработки данных до оценки
моделей ................................................... 419
Выводы ....................................................... 432
Рекомендации по дальнейшему изучению ......................... 433
Заключение ................................................... 433
Глава 11. Путь Python-разрабогчика .............................. 434
Пути дальнейшего обучения .................................... 434
Углубление в специализации ................................ 434
Книги для вдохновения ..................................... 435
Участие в open-source проектах ............................... 436
Почему это важно? ......................................... 436
Как начать? ............................................... 436
Заключение ................................................... 437
Список источников .......................................... 438
Об авторе
Камалова Юлия Борисовна — опытный преподаватель и инженер, специали-
зирующийся на информационных технологиях и анализе данных. Сейчас она
занимает должность старшего преподавателя на Кафедре информационных
технологий в Финансовом университете при Правительстве Российской Фе-
дерации, где обучает студентов математике, управлению данными с исполь-
зованием PostgreSQL, программированию на Python и машинному обуче-
нию. Юлия Борисовна активно участвует в научной работе. Она преподавала
в Центре дополнительного образования МГТУ имени Н. Э. Баумана, где вела
занятия, посвященные Python и информационной безопасности.
Карьера Юлии Борисовны началась в 2008 году, когда она работала лабо-
рантом в компании, занимающейся экспертизой промышленной безопас-
ности. С тех пор она накопила опыт работы на различных кафедрах ИжГТУ,
включая «Приборы и методы контроля качества» и «Прикладная математи-
ка». В дополнение к этому Юлия Борисовна преподавала английский язык,
что позволило ей расширить свои педагогические навыки.
В 2020 году работала в коммерческой дирекции завода «Нефгемаш» в ка-
честве специалиста по тендерной документации и переводчика. В том же го-
ду она стала инженером 1 категории в Ижевском нефтяном научном центре
(«Роснефть»), где занималась разработкой информационной системы и со-
зданием базы данных. Этот опыт позволил ей углубить свои знания в области
автоматизации и внедрения новых технологий.
Юлия Камалова продолжает следовать своим интересам в области обра-
зования и инженерии, стремясь делиться знаниями и опытом с будущими
специалистами.
Введение
В современном мире информационных технологий знание языка программи-
рования Python становится все более важным и востребованным навыком.
Python — это универсальный язык, который широко используется для обра-
ботки данных, автоматизации процессов, разработки веб-приложений и во
многих других областях. Простота и читаемость делают Python идеальным
выбором как для начинающих программистов, так и для опытных разработ-
чиков.
Python поддерживает множество популярных библиотек и фреймворков,
таких как NumPy, Pandas, Matplotlib и Django, что позволяет разработчикам
и аналитикам эффективно решать самые разнообразные задачи. Эти возмож-
ности делают Python одним из самых популярных языков программирования
на рынке труда.
В последние годы Python стал одним из самых востребованных языков
программирования благодаря своей простоте, богатой экосистеме и при-
менимости в различных областях. Рассмотрим ключевые направления, где
Python находит свое применение, — от веб-разработки и до машинного обу-
чения.
Веб-разрабогка
Python активно используется для создания веб-приложений благодаря
своим мощным фреймворкам, таким как Django и Flask. Эти инструменты
позволяют разработчикам:
• Быстро создавать и разрабатывать веб-сайты и веб-приложения.
Django, например, предлагает множество встроенных функций, таких
как управление пользователями, работа с базами данных и безопаснос-
тью, что позволяет сократить время разработки.
• Создавать RESTful API. Python позволяет легко разрабатывать API для
взаимодействия с фронтенд-приложениями, что делает его хорошим
выбором для разработки многоуровневых систем.
• Пользоваться простотой и ясностью синтаксиса. Это облегчает раз-
работку и поддержку кода, что делает его идеальным для командной
работы.
Анализ данных и визуализация
Python стал стандартом де-факто в области анализа данных. Благодаря
таким библиотекам, как Pandas, NumPy и Matplotlib, разработчики могут эф-
фективно обрабатывать, анализировать и визуализировать данные. Возмож-
ности включают:
* Обработку и анализ больших объемов данных. Pandas предоставляет
мощные инструменты для манипуляций с таблицами данных, что поз-
воляет легко выполнять такие операции, как фильтрация, агрегация
и преобразование.
• Визуализацию данных. Библиотеки, такие как Matplotlib и Seaborn, поз-
воляют создавать информативные графики и диаграммы для представ-
ления результатов анализа.
• Работу с данными из разных источников. Python может взаимодейс-
твовать с базами данных, API, веб-сайтами и файлами в различных
форматах (CSV, Excel, JSON и т. д.).
• Машинное обучение и искусственный интеллект.
Python стал ведущим языком для разработки приложений в области ма-
шинного обучения и искусственного интеллекта благодаря своему удобс-
тву и множеству библиотек, таких как TensorFlow, Keras и Scikit-learn. Здесь
Python предоставляет:
• Разработку и реализацию алгоритмов машинного обучения. Упрощает
создание моделей, обучение на данных и тестирование их производи-
тельности.
• Глубокое обучение. Библиотеки, такие как TensorFlow и PyTorch, позво-
ляют создавать сложные нейронные сети для обработки изображений,
текста и других типов данных.
• Простоту интеграции с другими инструментами. Python легко соче-
тается с другими языками и инструментами, что упрощает создание
сложных систем и прототипов.
Автоматизация и скриптование
Python также очень популярен в сфере автоматизации задач благодаря
своей простоте и мощным библиотекам для работы с системами и веб-серви-
сами. Возможности включают:
• Создание скриптов для автоматизации рутинных задач. Python поз-
воляет быстро писать скрипты, которые могут выполнять задачи, та-
кие как обработка файлов, взаимодействие с веб-сервисами и автома-
тизация рабочих процессов.
• Создание ботов и парсеров. С помощью библиотек, например Beautiful
Soup и Scrapy, Python позволяет извлекать и обрабатывать данные из
веб-страниц, что очень полезно для сбора информации и анализа.
Научные вычисления и инженерия
Python использует в своих приложениях, связанных с научными исследо-
ваниями и инженерией:
• Численные вычисления. NumPy и SciPy, которые предоставляют мощ-
ные инструменты для работы с многомерными массивами и чис-
ленными задачами, что важно в таких областях, как физика и инже-
нерия.
• Симуляции и моделирование. Python позволяет легко создавать модели
для тестирования гипотез и проведения экспериментов.
Таким образом, Python предлагает большие возможности для разра-
ботчиков, независимо от их уровня подготовки. Простота, обширная эко-
система библиотек и активное сообщество делают его подходящим для
решения множества задач, будь то создание веб-приложений, анализ дан-
ных, машинное обучение или автоматизация процессов. Освоив Python,
вы откроете для себя широкие горизонты в мире программирования
и технологий.
Цель книги
Цель этой книги — научить читателей основам работы с Python, позволяя
им уверенно использовать язык для решения повседневных задач, связанных
с программированием и анализом данных. Мы рассмотрим базовые концеп-
ции языка, синтаксис, структуры данных и основные алгоритмы.
Темы, такие как оптимизация производительности кода, проектирование
сложных приложений и работа с базами данных, не менее важны, но для на-
чинающих программистов лучше сначала освоить основы языка. Поэтому
акцент сделан на практических примерах и задачах, чтобы читатели могли
постепенно углублять свои знания и уверенно переходить к более сложным
аспектам Python.
Программное обеспечение для работы с Python
Для работы с Python и выполнения примеров использовалось бесплатное
программное обеспечение (ПО), такое как Anaconda [1], или стандартный
интерпретатор Python, доступный для всех основных операционных систем,
включая Windows, Linux и MacOS. Эти инструменты предоставляют удобную
среду для разработки и позволяют легко устанавливать необходимые библи-
отеки и модули.
Для изучения языка программирования Python вам потребуется устано-
вить на свой компьютер необходимое ПО. Вы также можете воспользоваться
готовыми решениями в виде онлайн-сервисов, которые позволяют запускать
код Python и работать с библиотеками без необходимости установки локаль-
ной среды.
Основная среда разработки для Python
Python — это язык программирования, для которого существует множес-
тво сред разработки. Одна из самых популярных — PyCharm. Это мощная
интегрированная среда разработки (IDE), которая предлагает множество
инструментов для работы с Python, включая автодополнение кода, отладку
и взаимодействие с системами контроля версий.
Официальный сайт: https://www.jetbrains.com/pycharm 12J.
Альтернативные среды разработки
Если вы предпочитаете легкие решения, можно использовать Jupyter Note-
book [ 3 J. Этот инструмент предназначен для работы с документами, содержа-
щими живой код, визуализации и текстовую информацию. Jupyter Notebook
особенно популярен среди исследователей и аналитиков данных.
Jupyter можно установить через пакетный менеджер Anaconda или с помо-
щью команды pip install notebook.
Онлайн-сервисы для работы с Python
Если вы хотите избежать установки ПО, то .можете воспользоваться он-
лайн-сервисами, такими как Google Colab. Этот бесплатный инструмент поз-
воляет писать и запускать код Python в браузере и предоставляет доступ к об-
лачным ресурсам, включая графические процессоры для обучения моделей
машинного обучения.
Официальный сайт: https://colab.research.google.com [4].
Пользуясь этими инструментами, вы сможете легко начать изучать Python
и использовать его возможности для решения различных задач.
Весь код, графики, рисунки, диаграммы, приведенные в этой книге, мож-
но взять здесь: https://colab.research.google.com/drive/letWWCRVv9qC9xq9S5fg
GmirPWhQgKnx)?usp=sharing или здесь: https://addons.eksmo.ru/it/P)’hton_s_
nulya_code.7z.
Глава 1
Введение
в программирование
на языке Python
Цели, задачи и основные
понятия раздела
Цель этой главы в том, чтобы познакомить читателя с основами языка Python,
его возможностями и функциональностью.
Python — это высокоуровневый язык программирования, который заре-
комендовал себя как один из самых популярных и универсальных языков,
подходящих для решения широкого спектра задач, от веб-разработки до ана-
лиза данных и машинного обучения [5].
Что значит «высокоуровневый язык программирования»? Это язык, кото-
рый предоставляет разработчикам удобный и абстрактный способ взаимо-
действия с компьютером {6].
Высокоуровневые языки программирования характеризуются следующи-
ми признаками:
1. Читаемость и простота. Они имеют синтаксис, который ближе к ес-
тественному языку или математическим записям. Это делает код более по-
нятным и легким для чтения, что упрощает процесс написания и сопровож-
дения программ.
2. Абстракция от аппаратуры. Эти языки абстрагируют детали работы
с аппаратным обеспечением, позволяя программистам сосредоточиться на
логике решения задач, не углубляясь в работу процессора, памяти и других
низкоуровневых компонентов системы.
3. Богатая стандартная библиотека. Высокоуровневые языки обычно
поставляются с обширными библиотеками встроенных функций и модулей,
что позволяет программистам быстро разрабатывать приложения, не зани-
маясь реализацией базовых функций с нуля.
4. Портативность. Программы, написанные на высокоуровневых язы-
ках, обычно могут быть запущены на различных платформах с минималь-
ными изменениями. Это значительно упрощает разработку и развертывание
приложений.
5. Управляемая память. Многие высокоуровневые языки, такие как
Python, имеют встроенные механизмы управления памятью, например сбор-
щик мусора, который автоматически освобождает память, когда она больше
не нужна. Это снижает риск ошибок, связанных с управлением памятью, вро-
де утечек памяти.
Среди высокоуровневых языков программирования можно назвать Java,
С, Ruby и т. д.
В противовес этому низкоуровневые языки, такие как ассемблер и машин-
ные коды, требуют от программистов более глубокого понимания архитекту-
ры компьютера и работы с его ресурсами, что делает их менее доступными
для начинающих разработчиков.
Перед тем как погружаться в более сложные концепции программирова-
ния, важно освоить инструмент, который позволит вам эффективно взаимо-
действовать с Python.
Вот несколько задач, которые нам предстоит решить:
1. Изучить основы работы в интерактивной среде iPython [7]. Это
мощная интерактивная оболочка для Python, которая предлагает удобный
способ выполнения кода, позволяет разработчикам получать мгновенный
отклик на введенные команды и облегчает процесс разработки и отладки.
Важно отметить, что iPython прекрасно подходит для экспериментов и быс-
трого прототипирования, что особенно полезно для начинающих програм-
мистов.
Почему7 iPython?
Он позволит вам:
• Выполнять код но строкам. Можно вводить и выполнять команды по
одной строке, что позволяет тестировать различные фрагменты кода
без необходимости создания полного скрипта.
• Работать с переменными. Можно создавать переменные прямо в ин-
терактивной среде и обращаться к ним в любое время, что значительно
ускоряет рабочий процесс.
• Использовать «магические» команды. iPython предлагает много «ма-
гических» команд (начинаются с %) и функций, которые облегчают
выполнение определенных задач. Например, можно быстро получить
информацию о переменной, вызвать графические интерфейсы, управ-
лять файлами и выполнять другие операции без написания лишнего
кода.
Обладая этими знаниями, вы сможете комфортно взаимодействовать
с Python и решать задачи более уверенно. Это закладывает фундамент для
изучения более сложных инструментов и фреймворков в будущем.
В рамках этой главы мы поставили перед собой несколько ключевых за-
дач, которые помогут вам успешно начать работу с Python.
2. Ознакомиться с интерфейсом Jupyter Notebook. Это веб-приложение,
позволяющее создавать документы, содержащие живой код, уравнения, ви-
зуализации и текстовые аннотации, и делиться ими. Мы подробно обсудим
его интерфейс и функциональность, которая включает:
• навигацию по файловой системе Jupyter;
• создание, редактирование и запуск ячеек с кодом;
• использование Markdown для оформления текста и создания докумен-
тации;
• сохранение и экспорт проектов в различные форматы.
3. Ознакомиться с синтаксисом языка Python. Он отличается простотой
и читабельностью, что делает его отличным выбором для начинающих про-
граммистов. Мы изучим основные элементы синтаксиса, такие как:
• переменные и типы данных (числа, строки, списки, кортежи, множест-
ва и словари);
• управляющие структуры (условные выражения, циклы);
• функции и области видимости;
• основные библиотеки Python и их использование.
Разберем ключевые инструменты и среды, которые помогут вам эффек-
тивно работать с Python, от iPython и Jupyter Notebook до Anaconda, PyCharm
и Google Colab.
Более подробно о программном
обеспечении
Чтобы начать изучение языка программирования Python, вам нужно устано-
вить специальное НО, которое поможет взаимодействовать с кодом. Разбе-
рем ключевые инструменты по порядку.
iPython
iPython — это интерактивная оболочка (консоль) для Python. Это не полно-
ценная среда разработки, но она предоставляет интерфейс, где вы можете
вводить команды и сразу же видеть результаты (рис. 1.1) [8].
Преимущества:
• Интерактивность. Можно вводить команды и получать мгновенные
результаты, что полезно для изучения языка.
* Работа с переменными. Позволяет быстро экспериментировать с ко-
дом, сохраняя переменные, чтобы использовать их позже.
• «Магические команды». В iPython есть специальные команды (начина-
ются с %) дня выполнения различных функций, таких как получение
информации о библиотеке, управление файлами, измерение времени
выполнения кода и других.
IP [У]:
IPython
Рис. 1.1. iPython
Jupyter Notebook
Jupyter Notebook — это инструмент, позволяющий создавать документы, со-
держащие живой код, визуализации и текстовую информацию в одном ин-
терфейсе и работать с ними (рис. 1.2).
jupyter
Рис. 1.2. jupyter Notebook
Jupyter Notebook — это интерактивная среда для работы с языком про-
граммирования Python, основанная на проекте iPython. Она использует тех-
нологию «чтение — оценка — вывод» (read-evaluate-print-loop, REPL), что
позволяет пользователям взаимодействовать с кодом в реальном времени,
выполнять блоки кода и сразу видеть результаты.
Для работы с Jupyter Notebook рекомендуется использовать пакет про-
грамм Anaconda. Он включает в себя Python, Jupyter Notebook и множество
других популярных библиотек и приложений, которые часто используют для
научных вычислений и обработки данных.
Установка Jupyter Notebook
Документация по установке доступна по следующему адресу: [Jupyter In-
stallation Guide] |9].
Порядок установки и запуска:
1. Загрузите Anaconda. Перейдите на официальный сайт Anaconda и за-
грузите установочный файл.
2. Установите Anaconda. Следуйте инструкциям на экране для заверше-
ния установки.
3. Запустите Jupyter Notebook через меню или консольную команду, введя
«jupyter notebook».
После выполнения команды программа откроется в вашем веб-браузере
и вы сможете создавать новые блокноты и работать с кодом.
Преимущества:
• Комбинированная работа. В одном документе можно создавать тексто-
вые описания (с помощью Markdown), добавлять код и выполнять его.
Это позволяет разнообразить презентацию материалов и делает рабо-
ту более наглядной.
• Интерактивность и визуализация. Очень удобно для анализа данных,
поскольку можно сразу видеть графики и таблицы рядом с кодом.
Google Colab
Google Colab (Collaboratory) — это облачный сервис для работы с Python,
предоставляющий возможности Jupyter Notebook, но с дополнительными
преимуществами (рис. 1.3).
colab
Рис. 1.3. Colab
Google Colab, также известный как Colab Laboratory, представляет собой
среду Jupyter, предоставляемую и поддерживаемую Google. Не требует ус-
тановки. Нужна лишь учетная запись Google. Для начала работы наберите
в поисковой строке «Google Colab» или перейдите по ссылке colab.research.
google.com (рис. 1.4).
Преимущества:
• Облачные ресурсы. Не нужно ничего устанавливать — весь необходи-
мый программный код запускается в браузере. Это особенно удобно
для пользователей, у которых ограниченные ресурсы на компью-
тере.
* Доступ к графическим процессорам (GPU). Google Colab предлагает
возможность использовать GPU для ускорения вычислений, что по-
лезно для обучения моделей машинного обучения.
Рис. 1.4. Приветственное окно Google Colab
Anaconda
Anaconda — это дистрибутив Python, который упрощает установку языка
и различных библиотек, а также предоставляет мощные инструменты для ра-
боты с данными и научными вычислениями.
Преимущества:
• Управление пакетами. Anaconda включает' в себя пакетный менеджер
conda, который позволяет легко устанавливать, обновлять и удалять
библиотеки.
• Создание виртуальных окружений. 11озволяет создать отдельные среды
для различных проектов, чтобы избежать конфликтов между библио-
теками.
• Включает Jupyter Notebook. Anaconda обычно устанавливается вместе
с Jupyter Notebook, что делает его удобным для работы с данными.
PyCharm
PyCharm — это интегрированная среда разработки (IDE), специально со-
зданная для языка Python. Это мощный инструмент, который помогает раз-
работчикам писать, отлаживать и тестировать код.
Преимущества:
• Автодополнение кода. PyCharm предлагает подсказки, что ускоряет
процесс написания.
• Отладка. Удобные инструменты для отладки кода, позволяющие нахо-
дить и исправлять ошибки.
• Интеграция с системами контроля версий. Поддерживает работу
с системами, такими как Git, что облегчает совместную работу над
проектами [10].
PyCharm не использует iPython напрямую, но в нем можно настроить
поддержку Jupyter Notebook и обеспечить выполнение кода в режиме ре-
ального времени. PyCharm и iPython могут работать вместе, но PyCharm
предназначен больше для разработки проектов, требующих структуриро-
ванного кода.
Интегрированная среда разработки (IDE)
IDE (Integrated Development Environment) — это программное обеспечение,
которое объединяет все средства, необходимые для разработки ПО. IDE пре-
доставляет инструменты для написания, тестирования и отладки кода.
Преимущества:
• Удобство. В IDE обычно интегрированы редактор кода, отладчик и тер-
минал, что значительно упрощает процесс разработки.
• Помощь в разработке. Такие инструменты, как автодополнение и под-
сказки, повышают продуктивность разработчиков, особенно для начи-
нающих.
Эти инструменты и среды помогают взаимодействовать с Python и об-
легчают изучение языка. С их помощью вы сможете запускать код, экспери-
ментировать с различными возможностями языка и писать свои программы
более эффективно. Выбор конкретного инструмента зависит от ваших пред-
почтений и задач.
Теперь, когда мы рассмотрели ключевые инструменты и среды, давайте
более подробно изучим, как они взаимосвязаны друг с другом и как взаи-
модействие между ними создает удобную экосистему для работы с языком
Python.
Как все это связано
iPython служит основой для Jupyter Notebook, обеспечивая интерактив-
ную среду выполнения кода. Если вы используете Jupyter Notebook, в дейс-
твительности вы работаете на базе iPython.
Jupyter Notebook и Google Colab имеют схожую функциональность, так
как оба используют iPython и позволяют выполнять код и визуализировать
данные, но Google Colab работает в облаке, в то время как Jupyter можно за-
пускать локально.
Anaconda объединяет все эти инструменты, предлагая простой способ уста-
новки и управления ими в одном пакете. Установив Anaconda, вы автоматичес-
ки получите доступ к iPython, Jupyter и множеству других полезных библиотек.
PyCharm можно использовать параллельно с iPython и Jupyter для раз-
работки более сложных проектов. Он предоставляет богатые инструменты
для программирования, но не является интерактивным инструментом, как
iPython или Jupyter.
Глава 2
Интерактивная среда
iPython
Что такое Python?
«Python — интерпретируемый, объектно ориентированный высокоуровне-
вый язык программирования с динамической семантикой. Встроенные вы-
сокоуровневые структуры данных в сочетании с динамической типизацией
и связыванием делают язык привлекательным для быстрой разработки при-
ложений (RAD, Rapid Application Development). Кроме того, его можно ис-
пользовать в качестве сценарного языка для связи программных компонен-
тов. Синтаксис Python прост в изучении, в нем придается особое значение
читаемости кода, а это сокращает затраты на сопровождение программных
продуктов. Python поддерживает модули и пакеты, поощряя модульность
и повторное использование кода. Интерпретатор Python и большая стандар-
тная библиотека доступны бесплатно в виде исходных и исполняемых кодов
для всех основных платформ и могут свободно распространяться» [11]. Гвидо
ван Россум, создатель Python
Python представляет собой технологию для разработки программного
обеспечения и создания прототипов. Он доступен на большинстве современ-
ных платформ, включая как 32-битные, так и 64-битные системы, а также мо-
жет работать с компилятором С и платформой Java.
Как описать язык программирования
Создание программы можно рассмат ривать как процесс коммуникации. По-
нимание программистом действий, то есть их значение, представляет собой
семантику.
Синтаксис языка программирования служит инструментом для передачи
этого значения. То, что интерпретатор выполняет на основе полученных дан-
ных, обычно называется прагматикой [12].
При разработке программного обеспечения крайне важно, чтобы в этой
цепочке не возникали ошибки. Синтаксис является строго формализованной
частью и может быть описан с помощью формальных систем, таких как син-
таксические диаграммы, что обычно учитывается в справочной документа-
ции. Инструментом реализации прагматики выступает сам интерпретатор
языка.
Давайте рассмотрим каждое из понятий с помощью ассоциативных при-
меров и сравнений.
Семантика
Язык и смысл
Представьте себе, что вы изучаете иностранный язык. Семантика в данном
контексте — это значение слов и выражений, которые вы учите. Например,
слово «стул» обозначает предмет, на котором можно сидеть. Таким образом,
семантика языка программирования — это те действия и операции, которые
происходят при выполнении кода, и как интерпретатор или компилятор «по-
нимает» эти действия.
Синтаксис
Правила грамматики
Синтаксис можно сравнить с правилами грамматики в языке. Напри-
мер, в русском языке существует правило, что сказуемое должно следо-
вать за подлежащим. Если вы скажете: «Стул на столе стоит», это будет
правильно, а если «На столе стул стоит», это тоже правильно, но иначе по
структуре. В программировании синтаксис определяет порядок и струк-
туру, которые вы должны соблюдать, чтобы код был понятен интерпрета-
тору, например:
print("Hello, World!")
Этот код корректен с точки зрения синтаксиса Python, в то время как
print "Hello, World!" — нет, потому что он не соответствует установленным
правилам.
Прагматика
Интерпретация намерений
Представьте, что вы находитесь на встрече, где обсуждается проект. 'Го,
как вы интерпретируете сказанное и как ваша команда воспринимает ваши
предложения, — это и есть прагматика. Это контекст, в котором происходят
действия, и выполнение их на практике. В программировании прагматика —
это то, как интерпретатор выполняет код и реализует его смысл. Например,
если код написан неправильно, интерпретатор может не справиться с его вы-
полнением — это будет ошибкой прагматики.
Представьте, что вы готовите блюдо ио рецепту.
• Ингредиенты и результат, который вы хотите получить (например,
идеальный торт), — это семантика.
• Сам рецепт с четкой структурой, где указаны составляющие и последо-
вательность действий (перемешать, выпекать и т. д.) — это синтаксис.
• Готовка: техника, уровень навыков и даже использование некоторых
подручных средств (например, форма для торта) — это прагматика.
Таким образом, все три аспекта играют важную роль в выполнении за-
дачи. Если рецепт написан правильно (синтаксис), вы понимаете, какие не-
обходимы ингредиенты (семантика), но не знаете, как правильно выпекать
(прагматика), результат может не оправдать ваших ожиданий.
История Python
История Python неразрывно связана с его создателем Гвидо ван Россумом, ко-
торый стал известен как Великодушный пожизненный диктатор (Benevolent
Dictator for Life, BDFL) [13]. Так описывают уникальную роль, которую он иг-
рал в управлении развитием языка на протяжении многих лет, а также идео-
логию, лежащую в основе его создания и эволюции.
Рождение языка
Python был задуман Гвидо ван Россумом в конце 1980-х годов как ответ на не-
обходимость в простом и доступном языке программирования, который был
способен решать сложные задачи. В 1991 году вышла первая версия Python
(0.9.0), и с того момента язык начал набирать популярность благодаря своей
читаемости и лаконичности кода [14].
Роль BDFL
Как BDFL, Гвидо ван Россум не только разрабатывал язык, но и определял
его философию, основываясь на принципах простоты и удобства использо-
вания. Его подход к управлению проектом сочетал в себе силу авторитарного
лидера и доброжелательность, что давало возможность слушать мнения со-
общества, но оставаться конечным арбитром в важных вопросах. Так он мог
быстро принимать решения и избегать затягивания процессов.
Benevolent Dictator for Life (BDFL) — эго термин, используемый для описания
определенной роли в управлении проектами с открытым исходным кодом, в час-
тности в контексте Python и его создателя Гвидо ван Россума. Этот титул подра-
зумевает, что руководитель проекта (в данном случае Гвидо) имеет окончатель-
ное слово в принятии решений о развитии и направлении языка или проекта, но
при этом действует во благо сообщества пользователей и разработчиков.
Основные аспекты роли BDFL:
1. Власть и ответственность. Гвидо ван Россум имел право принимать
окончательные решения по вопросам разработки Python. Это позволяло эф-
фективно и быстро решать проблемы и конфликты, возникающие в процессе.
2. Доброжелательность. Ключевой аспект роли BDFL — это понимание
и наличие интересов сообщества. Гвидо всегда стремился учитывать мнения
и предложения пользователей, что создавало положительный имидж и спо-
собствовало росту сообщества Python.
3. Баланс между контролем и демократичностью. Хотя у Гвидо была зна-
чительная власть, его подход основывался на открытости и вовлеченности
сообщества. Он активно поощрял обсуждение в списках рассылки и на фору-
мах, позволяя разработчикам и пользователям высказывать свои идеи и мне-
ние о развитии языка.
Прекращение роли BDFL
В 2018 юду Гвидо ван Россум объявил о своем решении уйти с поста
BDFL, изъявив желание избрать более демократический подход к управле-
нию проектом Python. После этого была сформирована «Управляющая груп-
па Python», ответственная за дальнейшее развитие языка. Это изменение
было принято для того, чтобы обеспечить более коллективное и устойчивое
управление проектом с учетом различных мнений разработчиков.
Влияние BDFI. на Python
Роль Гвидо ван Россума имела важное значение в становлении и развитии
Python:
* помогло обеспечить последовательность и целостность в принятии ре-
шений о языке;
• способствовало созданию сообщества, ориентированного на сотруд-
ничество и обмен знаниями;
• в значительной степени определило философию Python, основанную
на простоте и читаемости кода.
Таким образом, термин Benevolent Dictator for Life отражает уникальный
способ управления проектом Python, предоставляя однозначный фокус на
интересы сообщества, что способствовало его долгосрочному успеху и по-
пулярности.
Развитие языка
Под руководством ван Россума Python претерпел значительные измене-
ния и улучшения. В 2000 году была выпущена версия 2.0, ознаменовавшая
переход к современным возможностям, таким как поддержка юникода
и сборщик мусора. В 2008 году вышла версия 3.0, которая представляла со-
бой значительное обновление с новыми функциями и очищением синтак-
сиса. Вся эта работа была направлена на создание языка, который отвечал
бы требованиям разработчиков и пользователей, что было поддержано фи-
лософией BDFL.
В 2024 году наблюдается явная тенденция к увеличению популярности
анализа данных и машинного обучения с использованием языка Python. Эти
направления продолжают занимать лидирующие позиции благодаря своей
универсальности и мощным инструментам, доступным для разработчиков
и аналитиков. Вот основные аспекты этой тенденции:
1. Широкая популярность Python. Он остается одним из самых популяр-
ных языков программирования для задач, связанных с анализом данных
и машинным обучением. Простота в освоении и использования, а также чи-
таемость кода делают его идеальным для специалистов разного уровня.
2. Развитие библиотек и фреймворков. В 2024 году высоко востребованы
библиотеки, такие как Pandas для анализа данных, NumPy для численных вы-
числений, Scikit-learn для машинного обучения и TensorFlow и PyTorch для
глубокого обучения. Эти инструменты позволяют быстро и эффективно об-
рабатывать данные и создавать сложные модели.
3. Интеграция с большими данными. Растущая потребность в обработке
больших объемов данных с использованием технологий, таких как Н ,О, так-
же вносит вклад в популярность Python. Многие инструменты и системы об
работки больших данных поддерживают интеграцию с Python, что делает его
идеальным выбором для аналитических задач.
4. Образование и карьера. В связи с растущим спросом на специалистов
в области анализа данных и машинного обучения, учебные заведения пред-
лагают все больше программ и курсов, сосредоточиваясь на языке Python.
Это способствует подготовке нового поколения специалистов, готовых к ра-
боте в этих передовых областях.
5. Применение в различных отраслях. Python находит применение в самых
разных областях — от финансов и здравоохранения до маркетинга и произ-
водства. Компании активно используют машинное обучение для улучшения
процессов, повышения эффективности и принятия более обоснованных ре-
шений на основе данных.
Лицензия
Python — это язык программирования с открытым исходным кодом, а зна-
чит, он свободно распространяется и может быть использован как для лич-
ных, так и для коммерческих целей.
Свободное распространение
Любой желающий может скачать, использовать, модифицировать и рас-
пространять Python без каких-либо ограничений. Такое распределение
позволяет разработчикам, исследователям и компаниям работать с ним,
интегрировать его в свои проекты и адаптировать под свои нужды без
необходимости получения лицензий или оплаты за использование. Сво-
бодное распространение способствовало созданию огромного сообщест-
ва разработчиков, что также положительно сказалось на развитии языка
и его экосистемы.
Python Software Foundation License
Python лицензируется под Python Software Foundation License (PSF) — лицен-
зией с открытым исходным кодом. Она обладает несколькими характеристи-
ками:
• PSF License позволяет пользователям свободно получат]» доступ к ис-
ходному коду Python, что дает возможность изучать его, изменять
и адаптировать под свои нужды. Это способствует инновациям и сов-
местной разработке.
• Лицензия PSF также разрешает использование Python для создания
коммерческих продуктов. Вы можете разрабатывать и продавать про-
граммное обеспечение, основанное на Python, без необходимости уп-
лачивать лицензионные сборы или получать специальные разреше-
ния. Это делает Python привлекательным выбором для разработчиков,
стартапов и крупных компаний, желающих использовать его в своих
продуктах и решениях.
Таким образом, Python Software Foundation License и общая политика сво-
бодного распространения языка делают Python доступным и удобным инс-
трументом как для индивидуальных разработчиков, так и для организаций,
включая коммерческие проекты.
Портируемость
Портируемость — это способность программного обеспечения или кода
работать на различных платформах, операционных системах или устройс-
твах без необходимости внесения значительных изменений в исходный код.
В контексте языков программирования и ПО портируемость — это важный
аспект, поскольку она позволяет разработчикам использовать одну и ту же
программу в разных средах, экономя время и ресурсы.
Портируемость в контексте Python
Python выделяется высокой портируемостью, что обусловлено несколькими
факторами:
1. Кроссплатформенностъ. Язык Python доступен на различных операци-
онных системах, включая Windows, macOS и дистрибутивы Linux. Это поз-
воляет разработчикам разрабатывать приложения на Python, не беспокоясь
о платформозависимом коде.
2. Стандартные библиотеки. Python включает в себя множество стан-
дартных библиотек, которые обеспечивают одинаковый функционал на всех
поддерживаемых платформах. Это облегчает разработку кроссплааформен-
ных приложений, так как разработчики могут полагаться на стабильные
и унифицированные интерфейсы.
3. Интерпретация кода. Python является интерпретируемым языком,
то есть его код выполняется интерпретатором Python, который может быть
установлен на разных платформах. Это позволяет пользователям запускать
Python-скрипты на любой платформе, где доступен интерпретатор.
4. Обширное сообщество. Большое и активное сообщество разработчиков
Python создает множество библиотек и инструментов, которые способствуют
улучшению портируемости. Многие из этих библиотек специально разрабо-
таны для поддержки различных платформ и обеспечения совместимости.
Примеры портируемости
1. Код на Python. Если вы написали скрипт для обработки данных на
Python, его можно запустить как на Windows, так и на Linux, при условии, что
установлен интерпретатор Python.
2. Кроссплатформенные приложения. Многие популярные приложения,
такие как веб-сервисы и облачные решения, используют Python благодаря
его портируемости, что позволяет легко перемещать эти приложения между
серверами и средами развертывания [15].
Режим работы Python
Python предлагает два основных режима работы: стандартный (или скриптовый)
и интерактивный. Каждый из них имеет свои особенности и предназначение.
Стандартный режим
В стандартном режиме работы вы пишете код в текстовом файле с расшире-
нием .ру (например, python_program_name.py), а затем запускаете его через
интерпретатор Python. Этот режим удобен для больших программ или скрип-
тов, которые должны выполняться целиком [16].
Пример:
1. Создайте файл с именем hello.py и добавьте в него следующий код:
print("Hello, world!")
х = 2 + 2
print(x)
2. Запустите программу в командной строке:
python hello.py
Что происходит:
* Python интерпретирует весь код в файле, выполняя его по порядку;
• все выводимые данные отобразятся в терминале (например, програм-
ма выведет "Hello, world!" и "4" на экран).
Преимущества:
• подходит для более сложных задач;
• позволяет писать и сохранять длинные и сложные скрипты;
♦ обеспечивает возможность организации кода в функции и классы.
Интерактивный режим
Интерактивный режим, также известный как интерпретатор, позволяет вво-
дить команды и получать результаты немедленно. Его удобно использовать
для тестирования небольших частей кода, выполнения математических опе-
раций и быстрого прототипирования [17].
Пример:
1. Запустите интерпретатор Python, просто введя pychcn в командной строке:
Bash
2. В интерактивной среде введите:
»> print ("Hello, world!")
Hello, world!
»> 2 + 2
4
Что происходит:
• каждая команда выполняется сразу после того, как вы ее ввели;
• результаты немедленно отображаются па экране, что позволяет мгно-
венно видеть результаты кода.
11реимущества:
• удобен для быстрого тестирования небольших фрагментов кода;
♦ позволяет мгновенно получать обратную связь и проверять работу от-
дельных строк или выражений;
• простой и интуитивно понятный интерфейс для изучения и практики.
Сравним стандартный и интерактивный режимы (табл. 2.1):
Табл. 2.1. Режимы работы
Характеристика Стандартный режим Интерактивный режим
Форма ввода Исполняется из файла (напри- мер, python_program_name.py) Команды вводятся по оче- реди в терминале
Обратная связь Результаты выводятся после завершения выполнения всей программы Мгновенный вывод ре- зультатов после каждой команды
Предназначение Подходит для написания и вы- полнения сложных программ Подходит для тестирования кода, ..’бучения и быстрого прототипирования
Организация кода Поддерживает использование функций и классов, может содер- жать несколько строк кода Может легко вводить команды по одной, без структуры
Применение Чаще используется в производс- твенных системах и для разра- ботки приложений Чаще используется в учеб- ных целях и для быстрого тестирования
Оба режима работы Python имеют свои уникальные применения и пре-
имущества.
Стандартный режим предназначен для разработки более сложных прило-
жений, тогда как интерактивный режим полезен для быстрого тестирования
и обучения. Выбор зависит от целей и предпочтений.
Эффективность в Python
Эффективность в контексте программирования может быть рассмотрена
с двух важных аспектов: эффективность выполнения и эффективность раз-
работки [18]. Каждый из этих аспектов имеет свои специфические характе-
ристики и влияние на общий процесс программирования.
Выполнение
Эффективность выполнения относится к тому, как быстро и эффективно вы-
полняется код, написанный на Python, по сравнению с кодом, написанным на
других языках программирования. Важно понимать, что:
• Python — интерпретируемый язык, что делает его более медленным но
сравнению с компилируемыми языками, такими как С или C++ [19].
Однако, несмотря на это, Python показывает достаточно хорошую про-
изводительность для ряда задач, особенно в области анализа данных
и разработки веб-приложений.
* Существует множество инструментов и библиотек, которые помогают
улучшать производительность программ на Python. Например, исполь-
зование NuniPy для численных вычислений, которое написано на С,
позволяет значительно ускорить выполнение операций над массивами
по сравнению с обычными списками Python.
* Python поддерживает различные методы параллельного выполне-
ния кода, что может повышать его эффективность в многопоточных
и многопроцессорных системах. Использование таких библиотек, как
multiprocessing, позволяет разработчикам оптимизировать выполне-
ние программ, особенно в ситуациях с большими объемами данных
или ресурсоемкими задачами.
♦ Использование кэша (например, через functools.lru_cache) может значи-
тельно ускорить выполнение функций, которые часто вызываются с оди-
наковыми аргументами. Это особенно полезно в случаях рекурсивных
алгоритмов или функицпй, работающих с большими объемами данных.
Разработка
Эффективность разработки относится к тому, насколько быстро и с мини-
мальными затратами времени и ресурсов разработчик может создать качест-
венное программное обеспечение [19]. Этот аспект включает в себя несколь-
ко факторов:
• Читаемость и простота языка. Python славится читаемостью и лаконич-
ностью синтаксиса. Это снижает время, необходимое для написания и по-
нимания кода. Чистый и понятный код облегчает процесс работы в ко-
манде, когда несколько разработчиков грудятся над одним проектом.
* Обширная стандартная библиотека. Python поставляется с богатой
стандартной библиотекой, которая включает в себя множество гото-
вых модулей для выполнения распространенных задач. Это позволяет
разработчикам использовать готовые решения без необходимости пи-
сать код с нуля.
* Сообщество и документация. Сильное сообщество Python предостав-
ляет множество ресурсов, включая библиотеки, фреймворки и доку-
ментацию. Это упрощает поиск информации и практических решений,
что значительно ускоряет процесс разработ ки.
* Инструменты разработки. Использование современных инструмен-
тов и IDE, таких как PyCharm, VS Code или Jupyter Notebook, может
значительно ускорить процесс разработки. Эти инструменты часто
предлагают возможности автозаполнения, отладки, тестирования
и интеграции с системами контроля версий (например, Git), что повы-
шает общую продуктивность.
Тестирование
Эффективность тестирования также является важной частью общего процес-
са разработки. Хорошо организованный и проводимый процесс тестирования
может повысить качество кода и устранить ошибки на ранних этапах [20].
• Фреймворки для тестирования. Python поддерживает множество
фреймворков для автоматического тестирования, таких как unittest,
pytest и nose. Это позволяет разработчикам быстро и эффективно со-
здавать и запускать тесты, обеспечивая высокое качество кода.
• Тестирование на лету. Возможности интерактивного режима Python
позволяют разработчикам выполнять тесты и проверять результаты
кода в реальном времени. Это значительно ускоряет процесс поиска
и устранения ошибок.
Эффективность в Python включает в себя как эффективность выполнения,
так и эффективность разработки, а также тестирования. Благодаря высокой
читаемости кода, обширной стандартной библиотеке, мощным инструмен-
там разработки и активному сообществу Python стал одним из самых при-
влекательных языков программирования для разработчиков. Хотя он может
уступать в скорости выполнения по сравнению с некоторыми другими язы-
ками, преимущества, связанные с разработкой и тестированием, делают его
идеальным выбором для множества приложений.
Библиотеки Python
Python предлагает разработчикам обширные возможности за счет стандарт-
ной библиотеки и множества сторонних библиотек. Эти библиотеки помога-
ют решать множество задач, значительно ускоряя процесс разработки и по-
вышая качество результата [21].
Вопрос о различии между стандартными и сторонними библиотеками
в Python очень важен для понимания экосистемы языка. Давайте рассмотрим
основные отличия между ними [22].
Стандартные библиотеки
1. Включение в дистрибутив Python. Стандартная библиотека — это набор
модулей и пакетов, которые идут в комплекте с установленным интерпрета
тором Python. Это означает, что, когда вы устанавливаете Python, стандарт-
ная библиотека доступна вам сразу, без необходимости дополнительной ус-
тановки.
2. Поддержка разработчиков Python. Стандартную библиотеку разра-
батывают и поддерживают основные разработчики и сообщество Python.
Это гарантирует, что модули и функции имеют высокие стандарты качества
и совместимости.
3. Проверенная функциональность. Стандартные библиотеки прошли
множество тестов и проверок, что делает их более надежными для использо-
вания в производственном коде.
4. Сферы применения. Стандартная библиотека включает в себя модули
для выполнения множества фундаментальных задач, таких как работа с фай-
лами, обработка данных, математические вычисления и работа с Сетью. Это
обеспечивает разработчиков мощными инструментами без необходимости
искать внешние решения (табл. 2.2).
Табл. 2.2. Стандарт Hole библиотеки Python и их назначение
Назначение Библиотеки/Модули Описание
Text Processing re, string, unicodedata Работа с текстовыми данными, регулярные выражения
File I/O and Utils os, shutil, pathlib, csv, json Операции с файловой системой, работа с различными форматами файлов
OS and System- level sys, subprocess, signal, logging Взаимодействие с операционной системой, легирование
Networking and Internet socket, http, urllib, smtplib Сетевое программирование, работа с HTTP, отправка email
GUI Development tkinter, PyQt, PySide Создание графических пользова- тельских интерфейсов
Testing and Debugging unittest, doctest, pdb Модули для написания тестов и отладки кода
Concurrency and Parallel Processing threading, multiprocessing, asyncio Работа с параллельными и асинх- ронными вычислениями
Сторонние библиотеки
1. Независимые разработчики. Сторонние библиотеки разрабатываются
и поддерживаются независимыми разработчиками или организациями. Они
могут быть размещены в Python Package Index (PyPI) и доступны для установ-
ки через пакетные менеджеры, такие как pip.
2. Специфические функциональности. Сторонние библиотеки часто со-
зданы для решения специфических задач или для улучшения функциональ-
ности, отсутствующей в стандартной библиотеке. Например, библиотеки для
машинного обучения, такие как TensorFlow и Scikiblearn, обеспечивают про-
двинутые алгоритмы, коюрые не входят в стандартную библиотеку.
3. Уровень качества и поддержки. Поскольку сторонние библиотеки разра-
батываются различными командами и индивидуальными разработчиками,
их качество и уровень поддержки могут варьироваться. Хотя многие сторон-
ние библиотеки популярны и хорошо документированы, есть также менее
надежные или устаревшие решения.
4. Быстрая эволюция. Сторонние библиотеки могут быстро эволюциони-
ровать и адаптироваться к новым требованиям и технологиям. Это позволя-
ет им быть более современными по сравнению со стандартной библиотекой,
которая, как правило, нечасто изменяется.
Примеры различий
Стандартная библиотека:
• модуль math для выполнения математических операций;
• модуль datetime для работы со временем и датами;
• модуль ге для работы с регулярными выражениями.
Сторонние библиотеки:
• Pandas для анализа данных;
• Matplotlib для визуализации данных;
• Requests для удобной работы с HTTP-запросами (табл. 2.3).
Табл. 2.3. Сторонние (внешние) библиотеки Python
Специализация Библиотеки/Модули Описание
Numeric Processing NumPy, SciPy Работа с многомерными массивами, математические операции, научные вычисления
Data Manipulation Pandas Обработка структурированных данных (таблицы, временные ряды)
Visualization Matplotlib, Seaborn Создание визуализаций данных, пост- роение графиков и диаграмм
Machine Learning Scikit-learn.TensorFlow, PyTorch библиотеки для машинного обучения и глубокого обучения
Web Development Django. Flask, FastAPI Фреймворки для веб-разработки
Data Engineering Apache Spark, Apache Airflow Инструменты для работы с большими данными и потоковой обработки
Computer Vision OpenCV Компьютерное зрение и обработка изображений
Таким образом, стандартные и сторонние библиотеки в Python имеют
свои уникальные особенности и области применения. Стандартные библи-
отеки предоставляют надежные и проверенные решения для часто встре-
чающихся задач, которые доступны «из коробки». Сторонние библиотеки,
в свою очередь, обеспечивают более специализированные функции, которые
расширяют возможности Python. Так, Python становится мощным и гибким
языком программирования, способным удовлетворить потребности различ-
ных областей разработки.
Рассмотрим стандартные и сторонние библиотеки более подробно.
Стандартная библиотека Р) thon содержит набор модулей и пакетов, ко-
торые включают функциональность для выполнения наиболее распростра-
ненных задач. Это позволяет разработчикам использовать готовые решения
без необходимости установки сторонних библиотек. Некоторые из наиболее
популярных модулей стандартной библиотеки включают:
• codecs [23] предоставляет инструменты для работы с кодировками тек-
стов. С его помощью можно читать и записывать данные в различных
кодировках, например UTF-8 или ASCII. Это особенно полезно при
обработке текстовых файлов с различными форматами, обеспечивая
надежное преобразование текста между различными кодировками;
• math [24] обеспечивает доступ к основным математическим функциям
и константам. Модуль включает в себя функции для выполнения раз-
личных математических операций, таких как вычисление квадратного
корня (sqrt), синуса (sin), косинуса (cos), а также константы, такие как
л (пи) и е (основание натурального логарифма). Он особенно полезен
для выполнения математических расчетов, статистики и научных вы-
числений;
♦ ге [25] предоставляет инструменты для работы с регулярными выра-
жениями, что позволяет выполнять сложные операции с текстом, та-
кие как поиск, замена и извлечение подстрок. Регулярные выражения
позволяют эффективно обрабатывать строки и находить соответствия
в тексте, чго делает этот модуль незаменимым в задачах обработки
данных и текстов.
Некоторые из наиболее популярных сторонних библиотек включают:
• Matplotlib [26] — это одна из самых популярных библиотек для визуа-
лизации данных в Python. Она позволяет создавать статические, ани-
мационные и интерактивные графики. С ее помощью можно строить
линейные графики, гистограммы, диаграммы и многие другие виды
визуализаций, благодаря чему она идеальна для анализа данных и на-
учных исследований;
* Pandas [27] — это мощная библиотека для работы с данными и анализа
данных. Она предлагает высокоуровневые структуры данных, такие как
DataFrame и Series, которые позволяют легко манипулировать данными
и анализировать их. Pandas делает задачи обработки данных — очистку,
фильтрацию и агрегацию — более удобными и интуитивно понятными,
что особенно полезно в области анализа данных и статистики;
• SciPy [28] — это библиотека для научных и численных вычисле-
ний на Python. Она строится на основе NurnPy и предоставляет
дополнительные функции для работы с линейной алгеброй, оптимиза-
цией, интеграцией, интерполяцией, обработкой сигналов и статисти-
кой. SciPy часто используется в научных и инженерных задачах, пред-
лагая широкий спектр инструментов для решения связанных с ними
проблем.
Пакетный менеджер PyPI и pip
• PyPI [29] (Python Package Index) — это центральный репозиторий, где
размещено множество сторонних библиотек и пакетов, доступных для
Python. PyPI позволяет разработчикам находить, устанавливать и об-
новлять библиотеки, что делает процесс добавления новых инструмен-
тов в проекты наиболее простым;
• pip [30] — это официальный инструмент для управления пакетами
в Python, который позволяет разработчикам легко устанавливать и уп-
равлять библиотеками, хранящимися в PyPI. Установка новой библио
теки осуществляется с помощью команды pip install имя_лакета. На-
пример, чтобы установить библиотеку requests, можно использовать
pip install requests.
Сообщество и документация
• Документация [31]. Большинство библиотек Python имеет обширную
и качественную документацию, что позволяет разработчикам быстро
освоить их и эффективно использовать. Четкая документация в соче-
тании с примерами кода помогает ускорить процесс разработки.
• Сообщество. Активное сообщество, использующее Python, создает
множество обучающих материалов, руководств и статей. Это помогает
разработчикам находить ответы на возникающие вопросы и делиться
опытом с другими.
Модульность и повторное использование кода
• Модульность [32]. Библиотеки в Python позволяют организовать код
в модули, что способствует лучшему управлению проектами. Такой
подход облегчает чтение, тестирование и поддержку кода.
• Повторное использование кода. Использование библиотек и модулей
позволяет разработчикам избежать дублирования кода. Вместо на-
писания одних и тех же функций или классов можно использовать
существующие решения, что значительно упрощает процесс разра-
ботки.
Примеры применения библиотек
• Научные исследования. С помощью SciPy и NumPy исследователи могут
выполнять сложные математические операции и моделирование, что
делает эти библиотеки основополагающими для таких областей, как
физика, инженерия и количественные финансы.
• Анализ данных и бизнес-аналитика. Pandas и Matplotlib широко ис-
пользуются в бизнесе для анализа данных, создания отчетов и визуа-
лизации результатов, что помогает в принятии информированных ре-
шений.
• Машинное обучение. Библиотеки, такие как TensorFlow и scikit-learn (с
которыми Python также интегрирован), расширяю! возможности ана-
лиза данных и позволяют разрабатывать и обучать модели машинного
обучения.
Библиотеки — неотъемлемая часть экосистемы Python, которая обеспе-
чивает разработчиков мощными инструментами для решения множества
задач. Стандартная библиотека Python предоставляет широкий набор гото-
вых модулей для разных потребностей, тогда как сторонние — Matplotlib,
Pandas и SciPy — расширяют возможности языка, позволяя эффективно
обрабатывать, анализировать и визуализировать данные. Благодаря этому
Python особенно популярен среди разработчиков и исследователей в самых
разных областях.
Концепция Python Zen
Python Zen [33] — это принципы и философия, которые лежат в основе раз-
работки на языке Python. Их создал Тим Питерс (Tim Peters), и они содержат
краткие рекомендации и ясные ориентиры, которые помогают разработчи-
кам придерживаться определенной культуры программирования при напи-
сании кода.
Познакомиться с Python Zen можно, введя команду в интерпретатор
Python:
import this
При выполнении этой команды выведется текст, содержащий основные
принципы, сгруппированные в виде афоризмов,
1. Краси вое лучше, чем уродливое.
2. Явное лучше, чем неявное.
3. Простое лучше, чем сложное.
4. Сложное лучше, чем запутанное.
5. Плоское лучше, чем вложенное.
6. Разреженное лучше, чем плотное.
7. Читаемость имеет значение.
8. Частные случаи недостаточно особенные, чтобы нарушать правила.
9. Хотя практичность важнее чистоты.
10. Ошибки не должны проходить незамеченными.
11. Если их не заглушили намеренно.
12. Столкнувшись с неоднозначностью, отвергайте соблазн угадывать.
13. Должен существовать один — и, желательно, только один — очевид
ный способ сделать это.
14. Хотя сначала этот способ может быть неочевидным, если только вы не
голландец.
15. Сейчас лучше, чем никогда.
16. Хотя «никогда» часто лучше, чем прямо сейчас.
17. Если реализацию трудно объяснить — это плохая идея.
18. Если реализацию легко объяснить — возможно, это хорошая идея.
19. Пространства имен — чертовски отличная идея — давайте использо-
вать их чаще!
Зачем это нужно?
Python Zen служит неофициальными руководящими принципами для
разработчиков Python. Эти принципы помогают:
• Улучшить качество кода. Следуя рекомендациям Zen, разработчики
могут создавать более чистый, читаемый и поддерживаемый код.
• Снизить уровень неопределенности. Принципы ясности и простоты
помогают предотвратить путаницу и недоразумения в коде.
• Формировать культуру сообщества. Они также отражают дух и фи-
лософию сообщества Python, содействуя обмену идеями и практиками
между разработчиками.
Таким образом, Python Zen представляет собой важный аспект филосо-
фии Python, который помогает разработчикам ориентироваться в принятии
решений при написании кода. Эти принципы указывают на то, что язык и его
сообщество ценят качество, читаемость и простоту, отчего Python доступен
как для новичков, так и для опытных программмистов.
Выводы
Python — это мощный и универсальный язык программирования, который
обладает рядом ключевых преимуществ, почему он и популярен среди разра-
ботчиков различных уровней.
1. Свободное распространение. Python — это открытое ПО, и любой поль-
зователь может загружать, изменять и распространять его без платных ли-
цензий, что способствует доступности языка для широкого круга пользова-
телей.
2. Кроссплатформенностъ. Python работает практически на всех извест-
ных платформах, включая Windows, macOS и Linux. Это позволяет разработ-
чикам создавать кроссплатформенные приложения, которые могут функцио-
нировать в различных системах без значительных изменений кода.
3. Простота для изучения. Один из основных факторов популярности
Python — его простота. Легкий для понимания синтаксис делает Python иде-
альным языком для начинающих программистов. Начать работать с Python
можно быстро, что способствует легкому обучению и повышению квалифи-
кации.
4. Богатый набор функций стандартной библиотеки. Широкая библио-
тека Python предоставляет разнообразные модули и функции для решения
наиболее распространенных задач, от работы с файлами до математических
расчетов. Это позволяет разработчикам экономить время и сосредоточивать-
ся на бизнес-логике приложений.
5. Много доступных библиотек. 1ибкость Python дополняется множест-
вом сторонних библиотек, доступных через PyPI. Пакеты для анализа дан-
ных, визуализации, машинного обучения и многих других задач позволяют
разработать более сложные решения, не тратя время на разработку базовой
функциональности с нуля.
6. Интерпретируемость. Python — интерпретируемый язык, то есть код
выполняется строка за строкой. Это упрощает отладку и позволяет разработ-
чикам быстро тестировать и изменять код в интерактивной среде.
7. Интерактивность. С помощью интерактивных оболочек, таких как
iPython или Jupyter Notebook, разработчики могут экспериментировать с ко-
дом в режиме реального времени. Это особенно полезно для исследования
данных и прототипирования.
8. Большое сообщество. Активное и поддерживающее сообщество Python
способствует обмену знаниями, ресурсами и идеями. Обилие доступных
учебных материалов, документации и форумов позволяет разработчи-
кам быстро находить ответы на возникающие вопросы и делиться своим
опытом.
9. Поддержка множества парадигм. Python поддерживает различные
программные парадигмы, включая объектно ориентированное, функцио-
нальное и процедурное программирование. Это позволяет разработчикам
выбирать подходящие методы решения задач в зависимости от требований
проекта.
10. Адаптивность и применимость. Python находит применения в самых
различных отраслях — от веб-разработки до науки о данных, машинного
обучения и автоматизации. Его адаптивность позволяет использовать Python
во множестве проектов и решать широкий спектр задач.
Python — это язык, который сочетает в себе мощные функции, просто-
ту и благоприятную среду для разработки, отчего он хорош и для новичков,
и для опытных разработчиков. Благодаря его доступности и широким воз-
можностям, Python продолжает оставаться одним из самых популярных язы-
ков программирования в мире.
Глава 3
Управляющие
конструкции в Python:
ветвления, циклы,
исключения
Мы будем использовать следующие обозначения: в закрашенных рам-
ках — правила и определения, в светло-серых — примеры, в темно-серых —
результат (рис. 3.1).
Рис. 3.1. Обозначения
Алгоритм создания первой программы
в Google Colab
Чтобы начать работу с Python и создавать свои программы, вам понадобится
специальная среда для кодирования. Один из самых удобных и популярных
инструментов для этого — Google Colab.
1. Запустите среду colab Google Colab.
Откройте веб-браузер и введите в строку поиска запрос «Google Colab»
(рис. 3.2). Можно также перейти по ссылке https://colab.research.google.com для
быстрого доступа к платформе (рис. 3.2 и 3.3).
Q 1W«V44a
Рис. 3.2. Поиск Google Colab
Gogte «tab
YMcftog w*h Cotab 0*rt l erf »
C«s upOMM ю “ytbc.- j io
*• * «уев» 4 « « Сам —> W •*
Добро локапомг* a Cota©» - Cetota
botecaa
<i я — I I Я |nr w»» rwMM•»»»"» t
Gcogta Gstob
в»~~~~~ АИИЖЖМЯЯП
Рис. 3.3. Сайт Google Colab
2. Как только вы окажетесь на главной странице Colab, нажмите кноп-
ку «New Notebook» (рис. 3.4). Так вы откроете новую рабочую область,
в которой сможете писать и запускать свой код.
КОО
Browse Notebooks
News and Guidance
Рис. 3.4. Среда Google Colab
3. Как только откроется созданный файл, нужно нажать на кнопку «Вста-
вить кодовую ячейку ниже» (рис. 3.5), либо воспользоваться сочета-
нием клавиш Ctrl+M -t-B (зажав клавишу Ctrl, последовательно нажать
кнопки М, В).
СО Untit»Cd46.ipynb ☆
Файл HsuQnh вид Вставка Среда въвкммвмив Инструменты Справка
Q. Комлкдм + Код + Текст > Вй-лолннть все -
® 0 £• Пздааитьс*
ПОДКЛЮЧИТЬСЯ ’ *.
О Парамемныа Q Терминал
Рис. 3.5. «Вставить кодовую ячейку ниже»
4. Если нужно удалить кодовую ячейку, используйте значок удаления на
панели инструментов (рис. 3.6):
i •
£q C. Um>tled46.ipynb 1>
Файл
Изменит» Вид Вставка Среда выполнение Инструменты Справы
31 fi & Поягпит»»
О, Команды
+ Текст > Выполнит» все
ПОДКЛЮЧИТЬСЯ
с&|.мо
Е
S
О Переменные О Терытмал
Рис. 3.6. Удаление ячейки
5. Если нужно добавить комментарий, используйте значок добавления
комментария на панели инструментов (рис. 3.7):
С
£0 С Untitl«J46.ipynb <Г <2>
Фэи,
Изменит» Вид Вставка Среда выполнения Инструменты Справка
0 Подепит»ся
Команды
Текст > Выполнит» все
Подключиться ’
Выбрав ячейку
Е
Ссылка ив ячейку
Укиимт» ячейку
23
Добавит» комментарий
а
Открыт» нвстроики редакторе
Отразит» ячейку на вкладке
Ц1Лвант« фи-*>у
О Переменнме Q3 Терминал
Рис. 3.7. Добавление комментария
6. Если нужно добавить текстовую ячейку, нажмите на кнопку «Текст»
(таким образом мы добавляем заголовки и описания к программам)
(рис. 3.8).
|0 £ Unlitted46.ipynb ft <2>
Файл Изменить вм^^встаек- Среда выполнения Инструменты Справка
Ц Команды + Код + Текст О Выполнить осе -
СЗЕЗЭ
* I ф чмяизите Лрегр«и*Ч«б «ОД «ЛЯ <;гг**амру1т< «го С ЛОМИЯЬЯ «ккуссТМИМОГ» ИНТОАМКТ*.
э
В) ® л’> w™™»
Подключиться - а
----i ф 4 У Е :
<__________________J
D
Я
О Переменные О Терминал
□
Рис. 3.8. Добавление текстовой ячейки
7. После написания кода в кодовой ячейке необходимо нажать кнопку
«Выполнить все» (рис. 3.9):
। -j С, UntiUed46vynb О <2
Файл Изменит» Вид встаем
вылотения Инструменты Справка
Ф St Подмыться
О» Команды + Код + Текст > Выполнить осе
Подключиться
S
D
S
О Переменные И Терминал
Рис. 3.9. «Выполнить все»
Ветвления в Python
В Python для принятия решений используют конструкции if, elif и else. Они
позволяют выполнять разный код в зависимости от условий. Условие — это
логическое выражение, которое возвращает True или False [34].
После операторов if, elif и else в Python необходимо поставить двоето-
чие, а затем использовать отступ для обозначения блока кода, который будет
выполняться при выполнении соответствующего условия. Эта структура по-
могает Python понять, какие строки кода относятся к какому условию, и поз-
воляет организовать более читаемую программу.
Синтаксис ветвления в Python в общем виде выглядит так:
if условие!:
# Блок кода, который выполнится, если условие! истинно
elif условие2:
# Блок кода, который выполнится, если условие? истиннс
else:
# Блок кода, который выполнится, если ни одно из предыдущих условий
не истинно
Описание:
J. if начинает конструкцию ветвления. После if указывается условие,
а в конце ставится двоеточие :.
2. elif (можно использовать несколько раз) позволяет проверить допол-
нительные условия, если предыдущее условие было ложным. Также требует
двоеточия :.
3. else завершает конструкцию и выполняется, если все предыдущие усло-
вия были ложными. Требует двоеточия :.
Примечание. После каждого из этих операторов следует использовать
отступ (обычно 4 пробела или табуляция), чтобы обозначить блок кода,
который будет выполняться при соответствующем условии. Эта структу-
ра помогает Python понять, какие строки кода относятся к каждому кон-
кретному условию, и позволяет организовать программу более читабель-
но [35].
Приведенное выше описание простым человеческим языком в npoipa.M-
миовании имеет свое название — псевдокод.
Псевдокод — это удобный и неформальный способ описания алгоритмов
и логики программы с использованием простого, понятного языка, который
не привязан к конкретному языку программирования.
Пример;
if температура >= 30:
вывести "Жарко"
elif температура >= 15:
вывести "Тепло"
else:
вывести "Холодно"
Таким образом, благодаря использованию условий и отступов, вы можете
писать четкий и понятный код, который выполняет различные действия в за-
висимости от заданных условий.
Пример на языке Python
if temperature >= 3G:
print("Жарко")
elif temperature >= 15:
print("Тепло")
else:
print("Холодно")
Для того чтобы применить данный пример на практике, воспользуемся
новой функцией ввода информации input, а далее проверим условия темпе-
ратуры.
Функция input () [36] в Python используется для получения данных от
пользователя. Она останавливает выполнение программы и ждет, когда поль-
зователь введет значение и нажмет клавишу Enter.
Синтаксис функции input ()
input(prompt)
prompt — это необязательный параметр, позволяющий предоставить текст
(строку), который будет отображаться пользователю перед вводом данных.
Это помогает делать интерфейс программы более понятным.
Итак, в нашем примере запросим у пользователя с помощью функции
input ввод температуры с клавиатуры.
# Запрашиваем у пользователя ввод температуры
temperature = float(input("Введите температуру в градусах Цельсия:
Объяснение:
1. input("Введите температуру в градусах Цельсия: Эта часть кода вы-
водит на экран сообщение "Введите температуру в градусах Цельсия: ".Про-
грамма ожидает, пока пользователь введет значение (например, 25).
2. float(). Введенная строка (например, «25») преобразуется в число
с плавающей запятой с помощью функции float(). Это необходимо, чтобы
сравнивать температуру числовыми значениями в условиях.
3. temperature = ... Преобразованное значение сохраняется в переменной
temperature. Теперь мы можем использовать эту переменную для дальнейших
проверок.
Примечание. По умолчанию функция input () возвращает строку (тип
str). Поэтому важно преобразовывать ее в нужный тип (например, float, int
и т. д.), если планируется арифметическое сравнение.
Далее дополним программу проверкой введенного значения температу-
ры и выполнением соответствующих действий в зависимости от результата
проверки.
Полный код будет выглядеть следующим образом:
# Запрашиваем у пользователя ввод температуры
temperature = float(input("Введите температуру в градусах Цельсия: "))
f Проверяем условия температуры
if temperature >= 30:
print("Жарке")
elif temperature >= 15:
print("Тепло")
else:
print("Холоднс")
Скриншот запуска приведен ниже. Как видно на рис. 3.10, благодаря фун-
кции input произошло прерывание выполнения программы до тех пор, пока
пользователь не введет необходимую температуру.
# Запрашиваем у пользователе геод температуры
temperature = flcat(input(''EBefl,nTe температуру в градусах Цельсия: "))
я Проверяем условия температуры
if temperature >= Зв:
print("Жарко")
elif temperature >= IS:
print("Тепло")
else:
print("Холодно")
... введите температуру в градусах Цельсия: 110 |
Рис. 3.10. Запуск
Благодаря проверкам условий температуры выводится сообщение — жар-
ко, тепло или холодно. В этом примере мы ввели температуру 10, поэтому
выведено соответствующее сообщение: «Холодно» (рис. 3.11).
О и Запрашиваем у пользователя ввод температуры
temperature = flcat(input("BeeflHTe температуру в градусах Цельсия: ”))
# Проверяем условия температуры
if temperature >» 30:
print("Жарко")
elif temperature >= 15:
print("Тепло")
else:
print("Холодно")
... Eведите температуру в градусах Цельсия 10
Холодно
Рис. 3.11. Вывод
Стоит отметить, что внутри условий часто используются логические опе-
раторы: and, or, not. Это позволяет сочетать несколько проверок:
if temperature > 0 and temperature < 20:
print("Прохладно")
elif temperature >= 20 and temperature < 30:
print("Тепло")
else:
print("Лето в разгаре")
Qj) # Запрашиваем у пользователя -вод температуры
temperature = float(input(“Введите температуру в градусах Цельсия: "))
S Проверяем условия температуры
if temperature < 0:
print ( "Замерзло'')
elif temperature > 0 ard temperature < 20:
print("Прохладно")
elif temperature >= 20 and temperature < 30:
print("Tenno")
elif temperature >= 30:
print(”PeTC в разгаре")
else:
print("холодно")
I ••• Введите температуру в градусах Цельсия: | ]
Рис. 3.12. Пример
Объяснение:
1. if temperature < 0:. Если температура ниже нуля, программа выведет
"Замерзло".
2. elif temperature > 0 and temperature < 20:. Если температура больше
О, но меньше 20, программа выведет "Прохладно".
3. elif temperature >= 20 and temperature < 30:. Если температура больше
или равна 20, но меньше 30, программа выведет "Тепло".
4. elif temperature >= 30:. Если температура 30 градусов или выше, про-
грамма выведет "Лето в разгаре".
5. else:. Этот блок будет выполнен, только если ни одно из предыдущих
условий не выполняется, но в данном случае он не нужен, так как все возмож-
ные диапазоны уже охвачены.
Теперь программа обрабатывает:
• температуру ниже 0 (замерзло);
• температуру от 1 до 19 (прохладно);
• температуру от 20 до 29 (тепло);
• температуру 30 и выше (лето в разгаре).
Введем, к примеру, температуру 29 градусов и нажмем Enter (рис. 3.13):
ф й Запрашиваем у пользователя ввод температуры
temperature = float(lnputi”BeewTe температуру в градусах Цельсия: "))
й Проверяем условия температуры
if temperature < 0:
print("Замерзло”)
elif temperature > 0 and temperature < 20:
pri nt("Прохладно")
el if temperature >= 20 and temperature < 30:
print("Тепло")
elif temperature >= 30:
print("/leio в разгаре")
rise:
print("Холодно")
• •• Bi едите температуру e- градусах Цельсия: |2S ~ ~|
Рис. 3.13
Программа выдаст сообщение «Тепло» (рис. 3.14).
Ф й Запрашиваем у пользователя ввод температуры
temperature = float(input("BeeAHie температуру в градусах Цельсия: "))
й Проверяем усл ;зия температуры
if temperature < 0:
print("Замерзло")
elif temperature > О апо temperature < 20:
print("Прохладно")
elif temperature >= 20 and temperature < 30:
print("Тепло")
elif temperature >= 30:
print("fleTo в разгаре")
else:
print("Холодно")
... Введите температуру в градусах Цельсия: 29
Тепле
________________________________________________________________________________________________
Рис. 3.14
Иногда встречаются вложенные конструкции (37] — когда внутри if или
elif размещена еще одна проверка (рис. 3.15):
if temperature >= 0:
if temperature < 10:
print("Свежо")
else:
print("Тепло")
else:
print("Мороз")
(Q) * * Запрашиваем у пользователя ввод температуры
temperature = floa1( input ("Введите температуру ъ градуса»: Цельсия: "))
if temperature >= . .
if temperature < 10:
print(“Свежо”)
else:
print(“Тепло")
else:
print("Мороз")
Введите температуру в градусах Цельсия (б
Рис. 3.15
Объяснение:
1. Первый уровень условия (if temperature >= 0:) проверяет, не отри-
цательна ли температура. Если температура больше иди равна 0, проверка
продолжается.
2. Второй уровень условия (if temperature < 10:): если температура боль-
ше или равна 0, но меньше 10, программа выводит "Свежо".
3. else:. Если температура больше или равна 10, программа выводит "Теп-
ле".
4. else: на первом уровне. Если температура меньше 0, программа выво-
дит "Мороз".
Теперь программа обрабатывает:
• температуру ниже 0 (мороз);
• температуру от 0 до 9 (свежо);
• температуру 10 и выше (тепло).
Введем, к примеру, 5 градусов (рис. 3.16).
О # Запрашиваем у п льзоьателя ввод температуры
temperature = float(input("Введите температуру в градусах Цельсия: "))
if temperature >= 6--
if temperature < le:
print("Свежо")
else:
print("Tenao“)
else:
print("Мороз")
••• Введите температуру в градусах Цельсия 5
Свежо
Рис. 3.16
Программа вывела сообщение «Свежо».
Однако слишком глубокие вложения усложняют восприятие кода. В таких
случаях стоит рассмотреть объединение условий с помощью логики или вы-
нести проверки в отдельные функции.
Еще один вариант — применение конструкции if в сокращенной форме,
так называемого тернарного оператора.
Тернарный оператор — это короткая форма записи условного выражения,
которая позволяет выбрать одно из двух значений в зависимости от усло-
вия [38]. Оператор помогает писать компактный и читаемый код, заменяя
полноценные конструкции if-else.
В Python синтаксис тернарного оператора выглядит так:
<значение!> if <условие> else <.значение2>
Пример:
аде = 20
status = "Взрослый” if аде >= 18 else "Несовершеннолетний"
print(status) * Выведет: Взрослый
Здесь, если условие age >= 18 истинно, переменная status получит значе-
ние "Взрослый", в ином случае — "Несовершеннолетний".
Пример:
# Задаем возраст
аде = 20
# Условное выражение для определения статуса
status = "Взрослый" if age >= 18 else "Несовершеннолетний"
# Выводим статус
print(status) # Выведет: Взрослый
Объяснение:
1. аде = 20. Задаем переменную аде со значением 20. Это может быть лю-
бой возраст, который вы хотите проверить.
2. Условное выражение, status = "Взрослый" if аде >= 18 else "Несовер-
шеннолетний":
• если аде больше или равен 18, переменная status получит значение
"Взрослый";
• если аде меньше 18, status будет "Несовершеннолетний".
3. print (status). Эта строка выводит переменную status на экран.
Если вы запустите этот код и если значение переменной аде равно 20, про-
грамма выведет "Взрослый". Также можно изменить значение аде для провер-
ки разных случаев (рис. 3.17).
Q W Задаем озраст
age » 26
» Условное выражение для определения статуса
status = "Взрослый" if age >= 28 else "Несовершеннолетний"
# Выводим статус
print(status) в Выведет: Взрослый
— Взрослый
Рис. 3.17
Использование тернарного оператора удобно, когда нужно выбрать одно
из двух значений на основе маленького условия, — он делает код более корот
ким и лаконичным по сравнению с полноценной конструкцией if-else.
При работе с ветвлениями важно помнить, что Python проверяет условия
сверху вниз и останавливается при первом истинном. Поэтому порядок про-
верок влияет на результат. Часто сначала проверяют более узкие или приори-
тетные условия, а потом — более общие.
Циклы в Python
В Python есть два ключевых способа повторять действия: циклы for
и while [39].
Цикл for отлично подходит для обхода элементов в различных коллекци-
ях, будь то списки, кортежи, строки и т. п.
Цикл while продолжает работу до гех пор, пока выполняется заданное ус-
ловие.
Цикл for
Псевдокод:
для каждого элемента в коллекции:
выполнить блск кеда
Объяснение:
1. "для каждого элемента в коллекции". Мы хотим взять каждый элемент из
группы (коллекции). Например, если у нас есть список чисел, посмотрим на
каждое из них одно за другим (например, 1,2, 3 и т. д.).
2. "выполнить блок кода". Для каждого взятого элемента делаем что-то оп-
ределенное (например, выводим это число на экран).
Синтаксис:
for элемент in коллекция:
# Блок кода, который выполняется для каждого элемента
Объяснение:
1. for говорит компьютеру, что мы начинаем цикл, который будет повто-
ряться для каждого элемента.
2. элемент — это временное название для текущего элемента, который мы
обрабатываем в данный момент (например, если находимся на числе 2, то
элемент будет равен 2).
3. in коллекция указывает, что мы берем элементы из определенной груп-
пы (коллекции). Например, если это список чисел, указываем, что берем эти
числа.
4. : — это знак, который говорит о том, что начинается блок кода, который
мы будем выполнять для каждого элемента.
5. # Блок кода — здесь мы напишем, что именно хотим сделать с каждым
элементом (например, вывести его на экран).
Пример:
Псевдокод:
список = [1, 2, 3, 4, 5]
для каждого число в список:
вывести число
Синтаксис:
список = [1, 2, 3, 4, 5)
for числе in список:
print(число)
В результате на экране мы увидим:
1
2
3
4
5
Объяснение:
1. список = [1, 2, 3, 4, 5]. Как и в псевдокоде, мы создаем переменную
список, которая содержит те же самые пять чисел.
2. for число in список:. Используем команду for, чтобы сказать компью-
теру, что будем проходить по каждому элементу (числу) в списке, число — это
временное имя для каждого элемента, который мы обрабатываем.
3. print (число) — это команда, которая говорит компьютеру вывести чис-
ло на экран. Когда цикл выполнится, он покажет каждое число из списка от
1 до 5.
Таким образом, и в псевдокоде, и в Python, мы создали список чисел и ис-
пользовали цикл for, чтобы пройтись по каждому числу и вывести его значе-
ние. В результате на экране мы увидим:
1
2
3
4
5
Q список = [1, 2, 3, 4, 5]
*0’’ число in список
print(MHCflO)
... 1
2
3
4
5
Рис. 3.18
Цикл while
Псевдокод:
пека условие истинно:
выполнять блск кеда
Объяснение:
1. пека условие истинно: говорит компьютеру, что мы будем выполнять
блок кода до тех пор, пока это условие остается истинным. Если оно стано-
вится ложным, цикл останавливается.
2. выполнять блск кода. Внутри блока пишем команды, которые должны
выполняться, пока условие истинно.
Синтаксис:
while условие:
# Блок кода, который выполняется, пока условие истинно
Объяснение:
1. Используем while, чтобы начать цикл.
2. условие — это логическое выражение, которое проверяется. Если оно
истинно, выполнение переходит в блок кода ниже.
3. : в конце строки говорит о начале блока кода.
4. Все команды внутри блока должны иметь одинаковый отступ, чтобы
показать, что они относятся к этому циклу.
Пример:
Псевдокод:
счетчик = О
пока счетчик < 5:
вывести счетчик
счетчик = счетчик 4 1
Объяснение:
1. счетчик = 0. Создаем переменную счетчик и присваиваем ей значение 0.
Для нее это начальное значение.
2. пока счетчик < 5:. Говорим, что будем продолжать выполнение блока
кода до тех пор, пока счетчик меньше 5.
3. вывести счетчик. В блоке кода выводим текущее значение счетчика на
экран.
4. счетчик = счетчик + 1. Увеличиваем значение счетчика на 1 после каж-
дого вывода, чтобы он не оставался постоянным. Таким образом, в следую-
щей итерации (повторении) значение будет больше.
Синтаксис:
счетчик = 0
while счетчик < 5:
print(счетчик)
счетчик += 1 # Увеличиваем счетчик на 1
Объяснение:
1. счетчик = 0 — создаем переменную счетчик и устанавливаем ее в 0.
2. while счетчик < 5:—проверяем, меньше ли счетчик 5. Если да, выпол-
няем код внутри цикла.
3. print (счетчик) — выводим текущее значение счетчика.
4. счетчик += 1 — это сокращенный способ написать счетчик = счетчик +
1. Увеличиваем значение счетчика на 1.
(J счетчик = 0
while счетчик < 5:
print(счетчик)
счетчик += 1 # /величиьаем счетчик на 1
0
1
2
3
Рис. 3.19
Операторы break и continue
break используется, чтобы немедленно выйти из цикла. Когда программа
встречает эту команду, она завершает выполнение текущего цикла и перехо-
дит к коду, который идет после него.
continue пропускает текущую итерацию цикла и переходит к следующей.
То есть, когда программа встречает continue, она нс выполняет оставшуюся
часть кода в текущей итерации и сразу же начинает следующую [-40].
Общий синтаксис с break и continue:
Оператор в цикле:
if условие_для_break:
break # Прерывает цикл
if условие для continue:
continue # Пропускает текущую итерацию
Структура:
1. Оператор в цикле — это начало любого цикла (например, for или while).
Начинаем проходить по элементам или повторять код до тех пор, пока вы-
полняется условие.
2. if условие для break — эго проверка условия. Определяем, при каком
условии хотим прервать цикл. Например, это может быть просто проверка на
равенство или любое другое логическое условие.
3. break. Если условие для прерывания (как указано в предыдущем шаге)
истинно, программа выполняет оператор break, который немедленно завер-
шает выполнение текущего цикла. Все последующие итерации этого цикла
выполняться не будут.
4. if условие для continue — аналогичная проверка, по для другого дейс-
твия, о котором мы поговорим ниже. Это условие определяет, когда пропус-
тить выполнение оставшейся части кода текущей итерации.
5. continue. Если условие истинно, программа выполняет continue. Это оз-
начает, что текущая итерация заканчивается и программа переходит к следу-
ющей. Остальная часть кода в текущей итерации не будет выполнена.
Пример:
для i ст 0 до 9:
если i равно 5:
прервать цикл
если i четное:
перейти к следующей итерации
вывести i
Объяснение:
1. для i от С до 9:. Начинаем цикл, который будет проходить от О до 9.
2. если i равнс 5:. Если i равно 5, цикл прервется и больше не будет вы-
полняться (выход из цикла).
3. если i четное:. Если число четное, мы используем continue, чтобы про-
пустить оставшуюся часть кода для этой итерации и перейти к следующему
значению i.
4. вывести i. Если i не равно 5 и не является четным, мы его выводим.
Пример:
for i in range(10): # Перебираем числа от 0 до 9
if i == 5:
break # Прерывает цикл, когда i равно 5
if i % 2 == 0:
continue # Пропускает четные числа
print(i) # Выводит только нечетные числа
Объяснение:
1. for 1 in range (10):—начинаем цикл, который будет перебирать числа
от 0 до 9.
2. if i == 5: — если текущее значение i равно 5, вызываем break, и цикл
будет немедленно остановлен.
3. if i % 2 == 0: — проверяем, является ли i четным. Если да, вызываем
continue, чтобы пропустить оставшуюся часть кода и перейти к следующему
значению i.
4. print (i) — если i не равно 5 и не является четным, выводим i. Эт о зна-
чит, что мы выведем только нечетные числа до 5.
Когда вы выполните этот код, на экране вы увидите:
1
3
• Числа 0, 2 и 4 были пропущены, потому что они четные.
• Число 5 не было выведено, потому что цикл прервался, когда i стало
равно 5.
• Следовательно, были выведены только 1 и 3.
Оба типа циклов помогают автоматизировать повторение кода, но выби-
раются в зависимости от ситуации: for — когда заранее известна последова-
тельность, while — если нужно повторять, пока справедливо условие.
Цикл for в Python умеет работать не только с диапазоном чисел, создан-
ным функцией range() [41], но и с любыми итерируемыми объектами —
списками, кортежами, множествами, словарями (по ключам), строками и да-
же файлами. Например, можно перебирать символы в строке:
for letter in "Python":
print(letter)
Это выведет каждую букву на отдельную строку.
Давайте создадим пример с использованием цикла for, который переби-
рает буквы в строке "Python". Добавим небольшую логику, чтобы не просто
выводить каждую букву, а, например, проверять, является ли буква гласной
или согласной.
# Строка для перебора
строка = "Python"
# Перебираем каждую букву в строке
for буква in строка:
if буква.lower() in 'aeiou': # Проверка, является ли буква гласной
print(f"{буква} - гласная")
else:
print(f"{буква} - согласная")
Объяснение:
1. строка = "Python" — создаем строку, содержащую слово "Python".
2. for буква in строка: — начинаем цикл, который перебирает каждую
букву в строке "Python". В каждой итерации текущая буква будет сохранена
в переменной буква.
3. if буква.lower () in 'aeicu' : — этим условием проверяем, является ли
текущая буква гласной. Для этого преобразуем букву в нижний регистр с по-
мощью lower () и проверяем, содержится ли она в строке < aeiou >, где указаны
все гласные.
Примечание. Метод lower}) [42] в Python — это встроенный метод строк,
который преобразует все символы в строке в строчные. Он полезен, когда
необходимо привести текст к единому регистру, чтобы упростить сравнение
строк или обработку пользовательского ввода.
Синтаксис:
строка.lower()
строка — это исходная строка, на которой вызывается метод lower ().
4. print (f"{буква} - гласная"). Если буква гласная, выводим сообщение,
указывающее на это.
Буква f перед строкой в выражении print (f"{буква} - гласная") говорит
о том, что это форматированная строка (или f-строка) [43], которая была вве-
дена в Python 3.6. Форматированные строки позволяют встраивать значения
переменных прямо внутри строк, используя фигурные скобки {}.
Форматированные строки делают код более читаемым и удобным для
работы, так как нет нужды использовать дополнительные функции (на-
пример, format() или % для форматирования). Вместо этого вы просто
помещаете переменные в фигурные скобки внутри строки, предваряемой
буквой f.
Синтаксис:
f"строка {переменная} текст"
• строка — литерал строки, в которой вы хотите вставить значение пере-
менной;
• {переменная} — место, где будет подставлено значение переменной.
5. else: — если буква не гласная...
6. print (f"{буква} - согласная")— ...выводим сообщение, указывающее,
что это согласная буква.
Выполнив этот код, вы получите следующий вывод:
Р - согласная
у - согласная
t - согласная
h - согласная
с - гласная
п - согласная
Рис. 3.21
Мы использовали цикл for для перебора букв в строке "Python", а затем
определили, является ли каждая буква гласной или согласной, выводя соот-
ветствующее сообщение.
Также for удобно сочетать с функциями enumerateO и zip() для получе-
ния индексов элементов и параллельного обхода нескольких коллекций.
Функция enumerate ()
Функция enumerate () [44) в Python используется для получения как индексов,
так и значений из коллекции (например, списка или строки). Она возвращает
итератор, который генерирует пары (индекс, значение), что позволяет удобно
обрабатывать элементы вместе с их индексами.
Синтаксис:
enumerate(iterable, start=0)
• iterable — это любой объект, который можно перебирать (например,
список, строка, кортеж);
• start (необязательный) — это начальное значение для индекса (но
умолчанию 0).
Пример использования enumerate ():
список = ['кот', 'собака', 'попугай' ]
for индекс, животное in enumerate(список):
print(f"Индекс: {индекс}, Животное: {животное}")
Вывод:
Индекс: 0, Животное: кот
Индекс: 1, Животное: собака
Индекс: 2, Животное: попугай
Объяснение:
1. Создание списка:
список = [ 'кот', 'ссбака', 'попугай']
Создаем переменную описок, которая содержит три строковых элемента:
‘кот’, ‘собака’ и ‘попугай’. Он будет использоваться для итерации в цикле.
2. Использование enumerate ():
for индекс, животное in enumerate(список):
• enumerate (список) — это функция, возвращающая итератор, который
генерирует пары (индекс, значение) для каждого элемента в списке
список;
• индекс — это позиция элемента в списке (начиная с 0);
• животное — это текущее значение элемента списка список (то есть ‘кот’,
‘собака’, или ‘попугай’).
В этом цикле for каждую итерацию берется следующая пара (индекс, жи-
вотное), которые будут использованы в теле цикла.
3. Вывод результата:
print(f"Индекс: {индекс}, Животное: {животное}")
Используем f-строку, чтобы создать строку, которая будет включать теку-
щее значение индекса и животного. Когда код выполняется, для каждого эле-
мента списка будет выведено сообщение, которое содержит индекс и назва-
ние животного.
Функция zip()
Функция zip () [45] используется для объединения нескольких итерируемых
объектов (например, списков) в один, где каждый элемент является кортежем.
Это позволяет легко проходить несколько коллекций параллельно, получая
значения из каждого из них в одной итерации.
Синтаксис:
zip(*iterables)
*irerables — один или несколько итерируемых объектов, которые вы хо-
тите объединить.
Пример использования zip ().
В приведенном ниже коде происходит объединение и параллельная итера-
ция по двум спискам с помощью функции zip ():
имена = ['Анна', 'Боб', 'Клара']
возраст = [25, 30, 22]
for имя, воз in zip(имена, возраст):
print(f"[имя] - {воз} лет")
Вывод:
Анна - 25 лет
Боб - 30 лет
Клара - 22 лет
Объяснение:
1. Создание списков:
имена = ['Анна', 'Боб', 'Клара']
возраст = [25, 30, 22]
Создаем два списка: один (имена) с именами и другой (зозраст) с соответс-
твующими возрастами. Важно отметить, что каждый элемент на одной позиции
в списке имена соответствует элементу на той же позиции в списке возраст.
2. Использование zip():
for имя, воз in zip(имена, возраст)
Функция zip (имена, возраст) объединяет два списка в один итерируемый
объект, состоящий из кортежей. Каждый кортеж содержит элементы с одина-
ковым индексом из обоих списков. В данном случае мы получим пары: (< Ан-
на), 25), ('Боб', 30), ('Клара', 22). Па каждой итерации цикла переменные имя
и воз принимают значения из этих пар.
3. Вывод результата:
print(f"[имя] - {воз} лет")
Здесь используется f-строка для форматирования вывода. На каждой ите-
рации выводятся имя и соответствующий возраст в формате «Имя — Воз-
раст лет».
Сочетание for с enumerate () и zip ()
Эти функции удобно использовать с циклом for для обработки коллекций
с индексами или для прохождения по нескольким коллекциям одновре-
менно.
Есть общая схема, которая показывает, как можно сочетать функции
enumerateO и zip0 для итерации по нескольким коллекциям одновременно,
получая индексы и значения. Давайте рассмотрим общую схему и структуру
синтаксиса.
Общая схема синтаксиса:
for индекс, (значение!, значение2, ...) in enumerate(zip(iterable!,
iterable2, ...)):
f Ваш код, использующий индекс, значение!, значение2, ...
Объяснение:
1. enumerate () оборачивает любой итерируемый объект (обычно получен-
ный от zip()), чтобы возвращать пары индекс-значение. Используется, когда
нужен индекс текущего элемента.
2. zip () принимает несколько итерируемых объектов (например, списки,
кортежи и т. д.) и объединяет их в кортежи, где элементы с одинаковыми ин-
дексами из каждого объекта группируются вместе. Используется для парал-
лельной итерации по нескольким коллекциям.
3. for ... in ...: — стандартная конструкция цикла for, которая позво-
ляет перебирать элементы из итерируемого объекта.
4. (значение!, значение2, ...) —это способ распаковки кортежей, полу-
чаемых от zip (). Каждое значение будет присвоено своим переменным.
Пример объединения enumerateO и zip():
имена = [ 'Анна', 'Боб', 'Кг.ара' ]
возраст = [25, 30, 22]
город = ['Москва', 'Лондсн', 'Берлин']
for индекс, (имя, воз, грд) in enumerate(zip(имена, возраст, город)):
print(f"{индекс}: (имя) - {воз> лет, Город: {год}")
Объяснение:
1. Создание списков:
имена = ['Анна', 'Боб', 'Клара']
возраст = [25, 30, 22]
город = ['Москва', 'Лондон', 'Берлин']
Создаем три списка: имена, возраст и город, которые содержат имена лю-
дей, их возраста и города, где они живут.
2. Использование zip ():
zip(имена, возраст, город)
Функция zip () объединяет гри списка в один итерируемый объект, состоя-
щий из кортежей, где каждый кортеж будет содержать элементы с одинаковыми
индексами из всех трех списков. Например, результат будет выглядеть так: [ (< Ан-
на), 25, < Москва)), (<Боб>, 30, <Лондон)), (<Клара), 22, <Берлин))].
3. Использование enumerate ():
for индекс, (имя, воз, грд) in enumerate(...)
Используем функцию enumerate () для получения индекса и текущей груп-
пы значений (имя, воз, грд) из кортежей, созданных zip(). В результате на
каждой итерации индекс будет принимать значения 0, 1, 2, и каждая из пере-
менных имя, воз и грд будет принимать значения из соответствующего корте-
жа на каждой итерации.
4. Вывод результата:
print(f"{индекс}: [имя] - [воз] лет, Город: {грд}")
Здесь используется f-строка для вывода индекса, имени, возраста и горо-
да в читаемом формате. На каждой итерации будет выводиться информация
о каждом человеке: его индекс в списке, имя, возраст и город.
Вывод:
0: Анна - 25 лет, Город: Москва
1: Боб - 30 лет, Город: Лондон
2: Клара - 22 лет, Город: Берлин
Заключение:
• enumerate () помогает получить индексы и значения из коллекции, что
упрощает работу с массивами, особенно когда нужен индекс элемента;
• zip () позволяет легко проходить но нескольким коллекциям одновре-
менно, объединяя их в пары (или кортежи).
В цикле while важно следить за изменением условия — это гарантия того,
что цикл завершится. Если забыть обновить счетчик или изменить перемен-
ную, проверяемую в условии, можно получить бесконечный цикл.
При необходимости его можно прервать вручную с помощью break.
Оператор break позволяет досрочно выйти из цикла, как только достигну-
та нужная ситуация:
п = О
while True:
print(n)
n += 1
if n == 5:
break
А оператор continue пропускает остаток текущей итерации и переходит
к следующей:
for i in range(10):
if i % 2 == 0:
continue
print(i) # выведет только нечетные числа от 1 до 9
Циклы можно вкладывать друг в друга для обработки сложных структур,
например матриц или таблиц:
matrix = [(1, 2], [3, 4I]
for row in matrix:
for element in row:
print(element)
Но с ростом глубины вложенности лучше стремиться к оптимизации
и улучшению читаемости кода.
Кроме того, цикл можно сопровождать конструкцией else, которая сра
батывает, если он завершился естественным образом, без прерывания через
break. Это полезно для обработки ситуации, когда условие прервать цикл не
выполнилось:
for i in range(5):
print (i)
else:
print("Цикл завероен")
Обработка исключений
В Python для управления ошибками и необычными ситуациями создается
особая система — механизм обработки исключений |4б]. Он помогает ловить
возникающие во время работы программы сбои и реагировать на них так,
чтобы программа продолжила работу или завершилась аккуратно. Это дела-
ет код более устойчивым и защищенным от непредвиденных проблем.
Основные инструменты этой системы — конструкции try, except, finally
и команда raise.
try позволяет запустить блок кода и одновременно подготовиться к воз-
можным ошибкам.
except перехватывает все или конкретные исключения и управляет ими,
например выводом сообщения или выполнением определенных действий.
finally служит для выполнения кода, который должен произойти в лю-
бом случае, независимо от того, возникла ошибка или нет.
raise используется, чтобы самостоятельно инициировать исключение,
если возникает необходимость прервать выполнение или сигнализировать
о ситуации, требующей внимания.
Представьте, что вы собираетесь взобраться на непредсказуемую гору.
В блоке try вы готовитесь и начинаете подъем. Столкнувшись с препятс-
твием, с помощью except выбираете, как реагировать — отступить или поп-
робовать другой путь. В блоке finally, что бы ни случилось, вы аккуратно
упаковываете снаряжение и делаете выводы о ходе экспедиции. А команда
raise, как звонок колокола, который предупреждает о серьезной проблеме
или сигнализирует о необходимости особого внимания.
Пример:
try:
result =10/0
except ZeroDivisionError:
print("Ошибка: деление на ноль")
finally:
print("Блок finally выполнен")
В Python возможность управления исключениями — это своего рода щит,
предотвращающий неожиданное завершение программы из-за ошибок. Бла-
годаря этому механизму можно предусмотреть разные ситуации, которые
могут произойти во время выполнения, и корректно на них реагировать.
Конструкция try служит для охраны потенциально опасных участков ко-
да, где может возникнуть исключение. Например, деление на нуль — частая
причина ошибок:
try:
result =10/9
except ZeroDivisionError:
print("На ноль делить нельзя!")
Если происходит исключение, программа не завершит работу с ошибкой,
а перейдет в блок except, где можно, например, дать пользователю полезное
сообщение или выполнить альтернативные действия.
Иногда важно выполнить код в любом случае — будь то успешное завер-
шение или исключение, — и для этого используют блок finally. Например,
закрытие файла после чтения данных:
try:
file = open('somefile.txt', 'г')
data = file.readO
except FileNotFoundError:
print("Файл не найден.")
finally:
tile.close()
Даже если возникнет исключение, файл будет закрыт.
Иногда стоит самостоятельно инициировать исключение, например, при
встрече с некорректными данными, чтобы сигнализировать вызывающему
коду о проблеме. Тут пригодится команда raise:
def г.роверить_^-сзраст (age):
if age < 0:
raise ValueError("Возраст не может быть отрицательным!")
return age
проверить_возраст(-5)
Это вызовет исключение ValueError, которое можно поймать в другом
месте программы для дальнейшей обработки или логгирования.
Можно создавать свои собственные виды исключений, унаследовав их
от базовых. Например, для обработки ситуаций, связанных с некорректным
вводом в конкретной области, можно сделать гак:
class CustomError(Exception):
pass
def проверить число(value):
if value > 100:
raise CustomError("Число слишком большое!")
return value
try:
проверить число(150)
except CustomError as e:
print(f"Обнаружена ошибка: {e}")
Обработка исключений помогает не только предотвратить аварийное за-
вершение программы, но и сделать ее более предсказуемой, подходящей для
сложных систем, где необходимо контролировать каждый возможный сбой.
В совокупности эти инструменты позволяют проектировать устойчивые
и гибкие приложения, способные самостоятельно справляться с непредви-
денными ситуациями и предоставлять пользователю понятные сообщения
или резервные сценарии.
Выводы
В главе рассмотрены ключевые управляющие конструкции языка Python,
позволяющие реализовывать логику программ: ветвления, циклы и обра-
ботку исключений. Ниже — основные итоги по каждому блоку.
Ветвления (if, elif, else)
Позволяют выполнять разные блоки кода в зависимости от истинности
условий (логических выражений, возвращающих True или False).
Синтаксис требует:
• двоеточия после if, elif, else;
• отступов (обычно 4 пробела) для обозначения блока кода, относящего-
ся к условию.
Порядок проверок важен: Python выполняет первый истинный блок
и пропускает остальные.
Поддерживаются логические операторы (and, or, not) для комбинирова-
ния условий.
Возможны вложенные конструкции, но их избыток ухудшает читаемость.
Тернарный оператор (<значение1> if <условие> else <значение2>) позво-
ляет кратко записать выбор между двумя значениями.
Для ввода данных от пользователя используется функция input О, требу-
ющая преобразования типа (например, float (input (...)) для чисел).
Циклы
for — для итерации по коллекциям (списки, строки, кортежи и др.). Син-
таксис:
python
for элемент in коллекция:
# блок кода
while — повторяет код, пока условие истинно. Требует явного изменения
переменной условия, иначе возможен бесконечный цикл.
Операторы управления циклом:
break — досрочно прерывает цикл;
continue — пропускает оставшуюся часть текущей итерации и переходит
к следующей.
Циклы можно вкладывать друг в друга, но глубокая вложенность снижает
читаемость.
enumerate () — возвращает пары (индекс, значение) при итерации, удобно
для работы с индексами.
zip() — объединяет несколько коллекций в кортежи, позволяя итериро-
вать по ним параллельно.
Цикл может сопровождаться блоком else, который выполняется, если
цикл завершился без break.
Обработка исключений
Механизм try, except, finally, raise позволяет управлять ошибками
и делать код устойчивым.
try — блок кода, где возможно исключение.
except — обрабатывает конкретные или все исключения, предотвращает
аварийное завершение.
finally — код, выполняющийся всегда (например, закрытие файлов).
raise — принудительно вызывает исключение (например, при некоррек-
тных данных).
Можно создавать собственные исключения, наследуя от Exception.
Обработка исключений делает программу предсказуемой: она либо про-
должает работу, либо завершается корректно с информативным сообще-
нием.
Общий вывод
Управляющие конструкции — фундамент логики программ на Python.
Ветвления задают условное выполнение кода.
Циклы автоматизируют повторяющиеся действия, а вспомогательные
функции (enumerate, zip) расширяют их возможности.
Обработка исключений повышает надежность, позволяя реагировать на
ошибки без сбоев.
Правильное использование этих инструментов обеспечивает:
• читаемость и структурированность кода;
• гибкость в обработке данных;
• устойчивость к непредвиденным ситуациям.
Глава 4
Основные синтаксические
конструкции Python
Арифметические операторы +, /, И, %, **
Основные арифметические операторы в Python позволяют выполнять ши-
рокий спектр математических задач [47]. Помимо базовых вычислений, с их
помощью можно решать более сложные задачи и управлять результатами.
Сложение (+) объединяет значения или складывает числа.
# Суммируем иену двух товаров
total_price =45+30
print(f"Общая стоимость: {total_price} рублей") # Общая стоимость:
75 рублей
Объяснение:
1. Вычисление общей стоимости;
total_price =45+30
Создаем переменную total price и присваиваем ей значение, которое рав-
но сумме двух чисел: 45 и 30. Операция + их складывает. После выполнения
этой строки total_price будет равно 75.
2. Вывод результата:
print(f"Общая стоимость: (total_price) рублей")
Используем функцию print (), которая выводит информацию в консоль.
F-строка нужна для вставки значения переменного total price прямо в стро-
ку, которая будет выведена. Строка внутри print () выглядит так: «Общая
стоимость: 75 рублей», поскольку total_pnce равно 75. Это вызовет вывод
в консоль:Общая стоимость: 75 рублей.
Запуск это! о кода даст следующий вывод:
Общая стоимость: 75 рублей
Таким образом, код выполняет простое арифметическое сложение двух
чисел (45 и 30) и выводит результат в удобном формате.
Вычитание (-) уменьшает число на указанное значение.
I Дней до отпуска
days_.i.eft = 15-3
рг1п1(Г'Дней осталось: {days left}") # Дней осталось: 12
Умножение («) увеличивает число или масштабирует объект.
if Расчет площади квадрата со стороной 5
side length = 5
area = side_length * side_length
print(Г’Площадь квадрата: {area}") # Площадь квадрата: 25
Деление (/) делит число на другое и возвращает результат в виде числа
с плавающей точкой.
# Распределение 100 рублей между 4 студентами
share =100/4
print(f"Каждый получит: {share} рублей") # Каждый получит: 25.0 рублей
(Q К Распределение 100 рублей между 4 студентами
share в 100 / 4
print(f"Каждый получит: {share} рублей") • Каладмй получит: 25.0 рублей
••• Каждый получит: 25.0 рублей
Рис. 4.1
Целочисленное деление (//) определяет, сколько раз можно полностью
разделить число без остатка.
# Распределение 23 рыб псрсвну между А кошками
fishes_per_cat = 23 // 4
print(f"Рыб на кошку: {fishes per_cat}") # Рыб на кошку: 5
Остаток от деления (%) определяет, сколько осталось после целения.
# Остаток при делении кофе на чашки
cups = 10
coffee = 47
leftover = coffee % cups
print(f"Остаток кофе: {leftover} грамм") i Остаток ксфе: 7 грамм
Возведение в степень (**) используется для возведения числа в степень
или поиска степеней.
# Вычисление квадрата сксрссти
speed = 20
boosted speed = speed ** 2
print(f"Новая скорость: {boosted_speed} км/ч") # Новая скорость:
400 км/ч
Корень из числа можно извлечь, возводя число в степень 0,5 или 1/2.
# Расчет длины диагонали квадрата со стороной 4
Su.de = 4
diagonal = side ** 0.5 * 2 ** 0.5
print(f"Диагональ квадрата: {diagonal}"} f Диагональ квадрата: примерно
5.66
Модуль числа (abs) показывает абсолютное значение, например для рас-
четов с направлениями или разностями.
# Расчет разницы температур
temp_day = -5
temp_night = 3
difference = acs(tempjday - temp_nighc)
print(f"Разница температур: {difference} градусов") * Разница темпера-
тур: 8 градусов
Ф ины диагонали квадрата со стороной 4
side 4
diagonal = side “ 0.5 2 * 0.5
print(f"Диагональ квадрата: {diagonal}") # Диагональ квадрата: примерно 5.66
Диагональ квадрата: 2.8284271247461903
Рис. 4.2
Ф Н Расчет разницы температур
tpmp_day = 5
tewip_night » 3
difference = abs(tcep_day-temp_night)
print(f“Разница температур: {difference) градусов") ♦ Разница температур: 8 градусов
Разница температур: 8 градусов
Рис. 4.3
Эти примеры показывают, что арифметические операторы — это инстру-
менты не только для простых вычислений, но и для моделирования реальных
ситуаций, анализа данных и создания логики программы.
Основные правила приоритета операторов в Python
(от высшего к низшему)
1. Скобки ( ) — всегда выполняются первыми. Используются для явного
указания порядка операций.
2. Унарные операторы — например, унарный минус - и +, а также функции
abs ().
Унарные операторы применяются к одному операнду (значению или пе-
ременной). В отличие от бинарных, которые работают с двумя операндами
(например, +, -, *, /), унарные операторы воздействуют только на одно выра-
жение или значение.
3. Возведение в степень ** — высокая приоритетность, выполняется слева
направо.
4. Математические операции:
• Умножение *, деление /, целочисленное деление // и взятие по модулю
после возведения в степень, с одинаковым приоритетом.
• Операции сложения + и вычитания - после предыдущих.
5. Операторы сравнения, логические операторы (and, or) после арифмети-
ческих.
6. Присваивание = — самое низкое по приоритету, выполняется в кон-
це [48].
Пример. Найти значение выражения:
Ху * х у/у + Iх — У|3 — у/х + У
Решение:
import math
х = 5
у = 3
# Вычислим выражение:
# (х**у) * (у ** 0.5) + (abs(х - у) ** 3) - (math.sqrt(x + у))
result = (х ** у) * (у ** 0.5) + (abs(x - у) ** 3) - math.sqrt(x + у)
print(f"Результат вычисления: {result}")
Объяснение:
• х ** у — возводим число х в степень у (5Л3 = 125);
• у ** 0.5 — извлекаем квадратный корень из у(\3= 1.732);
♦ (х ** у) * * (у ** 0.5) —умножаем полученные значения (125 * 1.732
216.5);
* abs(x-y) ** 3 — возводим в куб модуль разницы (|5-3|л = 23 = 8);
• math.sqrt (х + у) — вычисляем квадратный корень суммы х и у (V(5+3)
= у 8 = 2.828).
Итоговое выражение складывает и вычитает эти части.
При выполнении получим:
Результат вычисления: 221.6725207759183
0 import meth
х 5
У - 3
• Вычислим выражение:
• (*Ж*У) * (У “ 0-5) ♦ (abs(x - у) 3) - (eath.sqrt(x ♦ у))
result » (х ** у) * (у *♦ 0.5) + (abs(x у) *♦ 3) eath.sqrt(x + у)
print(f"Результат вычисления: {result}")
••• Результат вычисления: 221.67792382136346
Рис. 4.4
Пример на использование операторов /, //, %.
Дано: есть некоторое количество яблок, которые нужно распределить по
коробкам.
Найти:
• сколько яблок останется в каждой коробке (целая часть);
• сколько яблок останется после заполнения коробок (остаток);
• сколько яблок в среднем будет в одной коробке с учетом дробной части
(обычное деление).
Решение:
яблок =53
коробок = 8
яблок_в_коробке = яблок // коробок # Целочисленное деление - сколько
яблок в каждой коробке целиком
остаток = яблок % коробок fr Остаток - сколько яблок останется
среднее_яблок = яблок / коробок # Обычное деление - среднее количество
яблок в коробке (включая дробную часть)
print(f"Яблок в каждой коробке: {яблок_в_коробке}")
print(f"Остаток яблок: {остаток}")
print(f"Среднее яблок в коробке: {среднее_яблок:.2f}")
Вывод:
Яблок в каждой коробке: 6
Остаток яблок: 5
Среднее яблок в коробке: 6.62
Объяснение:
• 53 // ; = 6 — в каждую коробку можно положить по 6 яблок, целая
часть от деления;
• 53 % 8 = 5 — останется 5 яблок, которые не уместились в коробки;
• 53 / 8 = 6.625 — среднее количество яблок в коробке с учетом долей.
Допустим, у нас есть очень большое число, например общее количество
секунд в году, и нам нужно:
• определить, сколько полных дней оно содержит;
• сколько осталось секунд после выделения полных дней;
• какая часть часа (например, в процентах) содержится в оставшихся се-
кундах;
• найти количество полных минут, которые можно выделить из остав-
шихся секунд.
Используем:
• 1 день = 86 400 секунд;
• 1 час = 3600 секунд;
• 1 минута = 60 секунд.
Решение:
# Общее количество секунд в году (не учитывая високосный год)
секунд_в_году = 365 * 8643D
# Вычисляем полные дни
пслныедни = секунд_в_году // 86400
# Остаток секунд после выделения полных дней
остаток секунд = секунд в_гсду % 86400
if Вычисляем количество полных часов в оставшихся секундах
полные часы = остаток_секунд // 36С0
# Остаток секунд после выделения полных часов
сстаток_г.осле_часоЕ = остаток_секунд % 36С0
# Вычисляем долю текущего часа в процентах
деля часа = (остаток_после_часов / 3600) * 100
# Вычисляем количество полных минут в оставшихся секундах
пслные_минуты = остаток_после_часов //60
print(f"Полных дней в году: {полные_дни}")
print(f"Автоостаток секунд после дней: {остаток_секунд}")
print(f"Процент текущего часа, содержащийся в оставшихся секундах: {до-
ля часа:.2f}%")
print(f"Полных минут в оставшихся секундах: {полные минуты}")
Объяснение:
♦ полные_дни = секунд_.-_году // 864СЭ — целочисленное деление, сколь-
ко полных дней в году (использует //);
• остаток секунд = секунд_в году : 86400 — остаток секунд после выде-
ления полных дней (использует ь);
• аналогично для часов и минут;
• позволяет выделить остаток времени после целых единиц;
• / используется для получения дробной части, например для вычисле-
ния процент а.
Вывод:
Полных дней в году: 365
Авгоостаток секунд после дней: О
Процент текущего часа, содержащийся в оставшихся секундах: 0.00%
Полных минут в оставшихся секундах: 0
(В году целых дней — 365, остаток — 0 секунд, так как расчет делается для
общего числа секунд. Для другого числа или при изменениях результат будет
разный.)
Операторы присваивания: =, —ь=, -=, *=, /=,
П=, %=, **=
Оператор присваивания =
Используется для сохранения значения в переменную.
score = 42 # Переменной score присвоено значение 42
Представим, что ведем счет в игре.
Оператор сложения с присваиванием +=
Добавляет значение справа к имеющемуся значению слева и сохраняет ре-
зультат в левую переменную:
coins = 10
coins += 5 # coins теперь равен 15 (10 + 5)
Игрок получил дополнительные монеты.
Оператор вычитания с присваиванием -=
Вычитает значение справа из значения слева и сохраняет результат слева:
health = 100
health -= 20 # health теперь 80 (100 - 20)
Персонаж потерял часть здоровья после битвы.
Оператор умножения с присваиванием ♦=
Умножает значение переменной слева на значение справа:
damage =10
damage *= 3 # damage теперь 30 (10 * 3)
У героя увеличивается урон за счет усиления.
Оператор деления с присваиванием /=
Делит значение слева на значение справа с сохранением результата в виде
числа с плавающей точкой:
speed = 60
speed /= 2 ff speed теперь 30.0 (60 / 2)
Например, скорость машины уменьшилась вдвое.
Оператор целочисленного деления с присваиванием //=
Делит значение слева на значение справа и сохраняет только целую часть
результата:
pages = 25С
pages_per_day =10
days = pages
days //= pages_per_day < days теперь 25 (целые дни для чтения)
Так мы подсчитаем, сколько целых дней потребуется для прочтения кни-
ги, если читать во 10 страниц в день.
Оператор остатка отделения с присваиванием %=
Сохраняет остаток от деления левой переменной на правую:
battery = 103
battery %= 30 # battery теперь 13 (остаток после циклической зарядки)
Представьте, что заряд багареи циклично сбрасывается каждые 30 еди-
ниц.
Оператор возведения в степень с присваиванием **= [49]
Возводит левую переменную в степень, равную правой части:
level = 2
level **= 3 # level теперь 8 (2 в кубе)
Можно представить, что уровень персонажа умножается по экспоненте.
Дополнительно: операции с переменными и строки
Переменные можно использовать для математических вычислений, а ре-
зультат сохранить в новую переменную:
а = 7
b = 3
с = а * Ь + 10 # с будет 31
Также можно складывать строки, это называется конкатенацией [50]:
first_name = "Анна"
last name = "Петрова"
full name = first name + " " + last name # "Анна Петрова"
Конкатенация — это операция соединения двух или более строк в одну.
В Python она осуществляется с помощью оператора + и позволяет создават ь
сложные строки из существующих, добавляя один фрагмент к другому.
1. Оператор +. Самый простой и очевидный способ — использовать его
для объединения строк.
а = "Привет"
b = ".Мир"
c=a+""+b# "Привет Мир"
2. Метод .join () удобен для объединения множества строк из итерируе-
мого объекта (список, кортеж и т. п.).
words = ["Я", "люблк?", "Python"]
sentence = " ".join(words) # "Я люблю Python"
3. Конкатенация через форматирование строк позволяет вставлять значе-
ния переменных прямо в строку.
name = "Анна"
аде = ЗС
text = Г'Меня зовут (name) и мне {аде} лет.
F-строки [51] — это способ быстро вставить значения переменных прямо
в текст. Представьте, что у вас есть имя и возраст и вы хотите написать с ними
предложение. Вместо того чтобы долго собирать строку, можно добавить f
перед кавычками и вставить переменные в фигурные скобки — Python сам
подставит их значения.
Как выглядят f-строки
• Строка начинается с буквы f или F перед кавычками.
* Внутри строки переменные и выражения помещаются в фигурные
скобки {}.
• Во время выполнения программы Python подставит значения этих пе-
ременных или результатов выражений прямо в строку.
Пример:
name = "Маша"
аде = 20
print(f"Меня зовут {name}, и мне {аде} лет.")
Вывод:
Меня зовут Маша, и мне 20 лет.
4. Форматирование с помощью метода . format () — более старый способ
форматировать и объединять строки:
text = "Меня зовут {} и мне {} лет.".format(name, age)
5. Использование оператора % — устаревший способ, который иногда
встречается в коде:
text = "Меня зовут %s и мне %d лет." % (name, age)
6. Конкатенация с помощью конструкции +=. Добавляет строку к уже су-
ществующей переменной:
text = "Привет"
text += " Мир" # Теперь text = "Привет Мир"
7. Конкатенация с помощью многократного написания строк. Python ав-
томагически объединяет соседние строковые литералы:
text = ("Это "
"одна строка "
"хотя и разбита на несколько")
Результат:
"Это одна строка хотя и разбита на несколько
8. Конкатенация через * (повторение строк). Хотя это не объединение
строк, а повторение одной, иногда бывает полезно вместе с +.
separator = * 10
text = "Привет" + separator + "Мир"
* Результат: 'Привет-Мир'
9. Использование тар() с str() и . join(). Если нужно объединить список
чисел или разных типов, сначала преобразуем их в строки:
numbers = [1, 2, 3, 4]
text = ", ".join(map(str, numbers)) * "1, 2, 3, 4"
О «1. Использование оператора ♦
a - "Привет"
b "Мир"
concat_plus «- a ♦ " " * b
9 2. Использование метода .join()
words - (“Я"» "люблю", "Python")
sentence_join " ". join(words)
Я 3. Использование f-строк
паве • “Дима"
age - Зв
f_string {"Меня зовут {паве} и мне {age} лет."
Я 4. Использование метода .fomwt()
format_str • "Меня зовут {} и мне {} лет.".format(паве, age)
я 5, Использование оператора X
oldstyle_fcreat "Меня зовут Xs и мне Xd лет." X (name, age)
9 6. Использование +•
text « "Привет"
text " Мир"
Я 7. Многосрочные литералы для автоматического объединения
multi_line - ("Это "
"одна строка "
"хотя и разбита на несколько")
Я 8. Использование • для повторения строки
separator • 10
repeated_string • "Привет" ♦ separator ♦ “Мир"
я 9. Преобразование чисел о строки и объединение с помощью join()
numbers • [1, 2, 3, 4]
joined_nuebers • ", ",join(map(str, numbers;)
Я Вывод всех результатов
print("Оператор ♦ concat_plu$)
print("MeTOfl .join():", sentencejoin)
print(“f-строка;", f_string)
print("Метод .format():“, foreat_str)
print("Оператор Xs", old_style_foreat)
рг!п1("Использование text)
print("Многоеречные литералы:", eulti.line)
print("Повторение строки repeated_string)
print("Объединение чисел с помощью join():“, joined.nuebers)
••• Оператор ♦: Привет Мир
Метод .join(): Я любло Python
f-строка: Меня зовут Анна и мне Зв лет.
Метод ,foreat(); Меня зовут Анна и мне 30 лет.
Оператор X: Меня зовут Анна и мне Зв лет.
Использование Привет Мир
Миогосрочмые литералы: Это одна строка хотя и разбита на несколько
Повторение строки *: Привет- Мир
Объединение чисел с помощью join(): 1, 2, 3, 4
Правила и рекомендации
по наименованию переменных
1. Имена переменных не должны совпадать с ключевыми словами
и встроенными функциями Python, такими как print, str, in и др.
2. В именах переменных допускается использовать только буквы, цифры
и символ подчеркивания .
3. Имена переменных не могут начинаться с цифры.
4. Рекомендуется давать переменным понятные и описательные имена,
которые отражают их назначение, при этом не слишком длинные.
5. Используйте имена, которые легко читаются и запоминаются.
6. Избегайте использования слишком коротких или абстрактных имен
(например, а, х), чтобы повысить читаемость кода.
7. Следите за единообразием стиля именования во всем проекте, чтобы
код был аккуратным и структурированным [52].
Табл. 4.1. Рекомендуемые и нерекомендуемые имена переменных
Хорошие имена Плохие имена Причина
usei_name a Однозначное и понятное имя
total_price X Неочевидное и абстрактное имя
numbe r_of_isems n Не информативное и слишком короткое
is^active flag Лучше использовать логичные имена
email_address data Слишком общее и неопределенное имя
max_rpeed maxspeedl23 Лучше использовать подчеркивания
file_path Ifilepath Нельзя начинать с цифры
user_age print Название встроенной функции
Типы данных: int, float и str
Python — язык программирования с динамической типизацией. Это значит,
что переменные не имеют фиксированного типа и тип значения определяется
во время выполнения.
В программировании понятие типа данных играет ключевую роль, пос-
кольку определяет, каким образом можно использовать переменную в раз-
личных операциях. В Python существует несколько базовых типов перемен-
ных, наиболее распространенные из которых — целые числа (int), числа
с плавающей точкой (float) и строки (str) 153J.
Правила определения типа переменной в Python
Целое число (int)
Для хранения целых значений, таких как количество учеников, возраст,
количество предметов.
Пример: количествс_учеников =25
Число с плавающей точкой (float)
Для хранения вещественных чисел, например температуры, веса, рассто-
яния. Даже если дробная часть равна нулю (например, 22,0), переменная все
равно будет типа float.
Пример: температура в комнате =22.5
Строка (str)
Для хранения текстовых данных, таких как название класса, имя, опи-
сание.
Пример: название класса = "ЗА"
Определение типа переменной
Для проверки типа переменной используйте функцию type 0.
Пример: print (type (количестве учеников))
Присвоение значения влияет на тип. Тип переменной определяется при-
своенным ей значением. После присвоения число с дробной частью преобра-
зуется в float, даже если дробная часть равна нулю.
Типы данных важно выбирать корректно:
• int для целых чисел без дробной части;
• float для чисел с дробной частью;
• str для текстовой информации.
Определение типа переменной
Чтобы быстро понять, каким типом обладает переменная, разработчики ис-
пользуют функцию type () (54]. Это очень полезно для отладки и проверки
правильности обработки данных.
аде = 30
pi_value = 3.14159
greeting = "Hello, Python!"
print(type(age)) * cclass 'int'>
print(type(pi_value)) # <class 'float'>
print(type(greeting)) # Cclass 'str'>
Особенности и нюансы типов
♦ Целое число (int) представляет целочисленные значения без дробной
части:count =42.
• Число с плавающей точкой (float) предназначено для хранения дроб-
ных чисел, а также целых чисел, зафиксированных с помощью точки:
temperature = 23. С. Даже если дробная часть равна нулю, тип все равно
считается float:
zero_point_zero = G.O
print(type(zero_point_zero)) ff cclass 'float'>
Преобразование между типами
Иногда возникает необходимость изменить тип данных, например, чтобы
выполнить арифметическую операцию или подготовить данные к выводу.
Для этого есть standard-built-in функции:
• int();
• float 0;
• str().
Пример:
pricestr = "199"
price int = int (price str) # '199'преобразуется к 199
discounted_price = price int * 0.9 if 179.1 — float
print (str (discounted price)) # '179.1' —превращение обратно в стро-
ку для вывода (рис. 4.15).
ф Л Определение типов переменных
age • 30
pi_value » 3.14169
greeting ’’Hello, Python!"
print(type(age)) # cclass 'int’>
print(type(pivalue)) # cclass 'float’>
print(type(greeting)) # cclass *str’>
ft Особенности типов
count 42
temperature - 23.0
zero_point_zero «0.0
print(type(zero_point_zero)) c cclass 'float'>
# Преобразование типов
price_str - "199"
price_int « int(price_str) и ’199' преобразуется к 199
discounted price - price_int 0.9 S 179.1 - float
print(str(discounted.price)) # '179.1'|
••• cclass *int‘>
cclass *float’>
cclass 'str’>
cclass 'float*>
179.1
Важные нюансы
• Влияние типов на результат: если участвуют числа разных типов,
Python применяет правила типа на этапе вычислений.
• Если хотя бы один операнд — float, результат также будет float.
• Деление: в Python 3 деление а / b всегда возвращает float, даже если
оба — int.
а = 8
b = 2
print(а / Ь) # 4.0 - float
print(type(а / b)) # <class 'float'>
c = 9
d = 3
print(c / d) #3.0
Целочисленное деление (//) возвращает целое число, отбрасывая дроб-
ную часть.
print(10 //3) #3
print(type(10 // 3)) # <class 'int'>
Строковые операции
Строки в Python можно не только объединять, но и повторять. Например:
phrase = "Gocd"
full_phrase = phrase * 3 # 'GcodGoodGcod'
print(full_phrase)
Для определения длины строки применяется функция 1еп(). Она возвра-
щает число символов в строке, что полезно при обработке текстовых данных.
message = "Python rocks"
lengthjnessage = len(message) # 12
print (ler.gth_ir.essage)
ф phrase » "Good"
full_phrase = phrase * 3 в 'GoodGoodGood'
print(full_phrase)
••• GoodGoodGood
message = "Python rotks"
lengthjnessage =» len(message) Я 12
print (lengthjnessage)
12
valuel = 18
value? = 12
isvaluel greater = valuel > value2 в Проверяем, больше ли valuel, чем value?.
print(is_value1_greater) Я Ожидаемый результат: True
Irue
Рис. 4.7
Q # Влияние типов на результат
а - 8
Ь = 2
print(a / Ь) » 4.0 - float
print(type(a / b)) # Cclass ’float*>
c 9
d = 3
print(c / d) 4 3.0
print(10 // 3) #3
print(typ«(10 // 3)) » <class 'ir»t'>
# Строковые операции
phrase “Good"
full_phrase phrase • 3
print(full_phrase) 0 'GoodGoodGood'
# Длина строки
message » “Python rocks"
length_mes«age = len(me£sage) • 12
print(length_message)
cclass 'float'»
3.0
3
<class 'int’>
GoodGoodGood
12
Более сложные сценарии
Рассмотрим групповые операции с типами.
1. Объединение строки и числа.
Перед выводом иногда нужно преобразовать число в строку, чтобы пра-
вильно соединить выражение:
score = 95
print("Your score is " + str(score))
2. Преобразование строки в число для арифметики.
Если пользователь вводит данные через функцию input (), то возвращает-
ся строка, которую нужно преобразовать:
hours = input("Enter hours worked: ") # строка
hours int = int(hours) # преобразование в число
pay_per_hour = 15.5
totaljpay = hours_int * * pay_per_hour
print ("Total pay: $" + str(total_pay)) .
Q f Объединение строки и числа]
score = 95
print(**Your score is " + str(score))
я Преобразование строки • число
hours ж input("Enter hours worked: ") • строка
hours_int = int(hours) # преобразование в число
pay_jper_hour 15.5
total_pay hours_int * pay_per_hour
print("Total pay: $" ♦ str(total_pay))
• Работа co словарем
studcnts_sccres {
"Alice": 88,
"Bob": 92,
"Charlie": 79
for гаме, score in students_scores.items():
print(f"{паве; scored {score} points.")
Your score is 95
Enter hours worked: 95
Total pay: $1472.5
Alice scored 88 points.
Bob scored 92 points.
Charlie scored 79 points.
Операторы сравнения
Операторы сравнения в Python [54] служат для проверки отношений между
значениями. Они возвращают логические значения, указывая, истинно (True)
или ложно (False) данное утверждение. Давайте рассмотрим основные опера-
торы сравнения и приведем по оригинальному примеру на каждый из них.
Основные операторы сравнения
• >: больше;
• >=: больше или равно;
• <: меньше;
• <=: меньше или равно;
• !=: не равно;
• ==: равно.
Примеры использования операторов сравнения:
1. Проверка на большее значение (>).
valuel =18
value2 = 12
is valuel greater = valuel > value2 # Проверяем, больше ли valuel, чем
value2.
print(is_valuel greater) * Ожидаемый результат: True
Результат:
True
2. Проверка на большее или равное значение (>=).
numl =25
пшп2 = 25
is_numl_greater_or_equal = numl >= num2 # Проверяем, больше ли numl,
чем num2 или равно ли.
print(is_numl_greater or_equal) # Ожидаемый результат: True
Результат:
True
3. Проверка на меньшее значение (<).
vail = 7
va!2 = 10
is vall_less = vail < val2 # Проверяем, меньше ли vail, чем val2.
print(is_vall_less) # Ожидаемый результат: True
Результат:
True
Charlie scored 79 points.
valuel « 18
value2 = 12
is_valuel_great«r = valuel > valueZ » Проверяем, больше ли valuel, чем value2.
print(ii_valuel_jgreater) # Ожидаемый результат: True
True
numl = 25
num2 •= 25
is_numl_greater_or_equal nuel > nu»2 « Проверяем, больше ли nural, чем num2 или равно ли.
print(is_nu«l_great«r_or_equal) • Ожидаемый результат: True
True
Q vail = 7|
val2 = 10
is_vall_less vail < val2 # Проверяем, меныве ли vail, чем val2.
print(is_yall_le$s) # Ожидаемый результат; True
••• True
x = 14
у x 14
is_x_less_or_equal x <• у # Проверяем, меньше ли х, чем у или равно ли.
print(is_x_less_or_equal) # Ожидаемый результат: True
Рис. 4.10
4. Проверка на меньшее или равное значение (<=).
х = 14
у = 14
is_x less or equal = x <= у # Проверяем, меньше ли х, чем у или равно ли.
print(is_x_less_or equal) # Ожидаемый результат: True
Результат:
True
5. Проверка на неравенство (!=).
alpha = 3
beta = 5
are_alpha_and_beta different = alpha != beta # Проверяем, не равны ли
alpha и beta.
print(are^alpha and beta differer.t) * Ожидаемый результат: True
Результат:
True
6. Проверка на равенство (==).
first_number = 42
second_number = 42
are first ano_secor.d_equal = first_number == secor.d_number
I Проверяем, равны ли first number и second^number.
print(are_first_and seoona_equal) # Ожидаемый результат: True
Результат:
True
True
© first_nueber = 42|
second_nu«ber = 42
are.first _a nd _ sec ond.equal first number еж second.nuaber
• Проверяем, равны ли first_numb*r и second..number.
print(are_first_and_second_equal) # Ожидаемый результат; True
... True
a - 5©
b - 3O
c » 50
is_condition_met = (a >= b) and (с x= a) t Проверяем, что а больше или равно b И с равно а.
print(isi_condition_met) в Ожидаемый результат: True
True
result_type type(is_valuel_greater)
print(result_type) # Ожидаемый результат: Cclass ’bool'>
<class ’bool’>
© a = 5
if a % 2 == 0: w Внимание! Используется двойное равно
print('The number is even.')
Рис. 4.11
7. Комплексные сравнения.
Объединим несколько операторов для более сложного логического вы-
вода:
а = 50
b = 30
с = 5С
is_condition_met = (а >= b) and (с == а) # Проверяем, чтс а больше или
равно b И с равно а.
print(is_ccndition_met) f Ожидаемый результат: True
Результат:
True
Типы данных логических выражений
Как видно из примеров, результат выполнения выражений с операторами
сравнения всегда генерирует значение логического типа данных (Boolean).
Это можно проверить с помощью функции type():
result_type = type(is_valuel_greater)
print(result_type) # Ожидаемый результат: <class 'ЬооГ>
Результат:
«class 'вос1'>
Проверка четности числа в Python
Проверка четности числа — одна из основных задач, с которой сталкиваются
программисты. Четное число — это число, которое делится на два без остат-
ка, тогда как нечетное — это число, которое при делении на два оставляет
остаток. В Python можно использовать оператор взятия остатка от деления %
для выполнения этой проверки.
Давайте рассмотрим различные способы проверки четности числа на трех
уровнях сложности: простой, средний и продвинутый.
Пример 1. Простой уровень
На первом уровне мы будем работать с одной переменной и выводить ре-
зультат на экран:
а = 5
if а ъ 2 == 0: # Внимание! Используется двойное равно '=='.
print('The number is even.')
else:
print('The number is odd.')
Результат:
The number is odd.
<class 'bool’>
Q a - 5
if a X 2 0: # Внимание! Используется двойное равно
print(’The number is even.’)
else:
print(’The number is odd.’)
I
The number is odd.
Ф numbers [1, 2, 3, 4, 5, 6]
for num in numbers:
if num X 2 == 0:
print(f’The number {num} is even.’)
else:
print(f’The number {num} is odd.')
••• The number 1 is odd.
The number 2 is even.
The number 3 is odd.
The number 4 is even.
The number 5 is odd.
The number 6 is even.
def chec k_even_odd(num):
if num % ? == 0:
return 'even'
else:
return ’odd'
Рис. 4.12
В этом примере проверяется четность числа, хранящегося в переменной
а. В данном случае, так как а равно 5 (нечетное число), программа выведет
сообщение о нечетности.
Пример 2. Средний уровень
На среднем уровне добавим возможность проверки нескольких чисел, ис-
пользуя цикл for для обхода списка:
numbers = (1, 2, 3, 4, 5, 6]
for num in numbers: if num % 2 == 0: print(f'The number {num} is even.')
else: print(f'The number {num} is odd.')
Результат:
The number 1 is odd.
The number 2 is even.
The number 3 is odd.
The number 4 is even.
The number 5 is odd.
The number 6 is even.
В данном случае программа проверяет четность для всех чисел в списке
и выдает соответствующее сообщение.
Пример 3. Продвинутый уровень
На продвинутом уровне мы создадим функцию, честность которой мож-
но проверить более гибким способом. Это позволяет повторно использовать
код и обрабатывать ввод от пользователя:
def check_even_odd(num):
if num % 2 == 0:
return 'even'
else:
return 'odd'
user_input = int(input("Enter a number: "))
result = checkeven odd(userinput)
print(f'The number {user_ir.put} is {result}.')
Результат:
Enter a number: 9
The number 9 is odd.
The number 5 is odd.
The number 6 is even.
ф Message "Hello, world!"
i»_univers»__present = ’universe' in message
• Проверяем, есть ли "universe’ в строке message.
print(is_universe_present) » Окодаегей результат: False
••• False
name ’"Alice"
if 'A' in name:
print("The letter ’A" is in the name.")
else:
print("The letter 'A' is not in the name.")
Рис. 4.13
В этом примере мы создали функцию check even_odd, которая принимает
на вход число и возвращает строку, указывающую на четность или нечет-
ность. Пользователь вводит число, и программа выводит соответствующий
результат. Проверка четности числа в Python может быть выполнена на раз-
личных уровнях сложности, от простого условия до функций, которые обра-
батывают пользовательский ввод.
Оператор членства in
Оператор членства in [56] используется для проверки принадлежности эле-
мента к последовательности, такой как список, строка, кортеж или множест-
во. Он возвращает логическое значение True, если элемент найден в последо-
вательности, и False, если нет. Использование оператора in делает код более
читабельным и упрощает проверку наличия элементов.
Примеры использования оператора in
1. Проверка отсутствия элемента в строке:
message = "Hello, world!"
is_universe_present = 'universe' in message
i? Проверяем, есть ли ’universe' в строке message,
print(is_universe present) # Ожидаемый результат: False
Результат:
False
The nunber 5 is odd.
The nunber 6 is even.
Q def check_even_odd(nun);
if nun X 2 « 0:
return * even'
else:
return ’odd'
us*r_input = int(input("Enter a number: "))
result check_even_odd(user_input)
print(f’The nunber {user_input} is {result}.’)
••• Enter a nunber: 5
The nunber 5 is odd.
Ql message = "Hello, world!"
is_universe_present = ’universe' in message
й Проверяем, есть ли 'universe' в строке message.
print(is_universe_pre$ent) • Ожидаемый результат: false
••• False
папе - "Alice"
if 'A' in name:
print("The letter ’A' is in the папе.")
else:
print("The letter ’A' is not in the папе.")
Рис. 4.14
В данном случае мы проверяем наличие подстроки < universe > в строке
message. Поскольку она отсутствует, результат будет False.
2. Использование в условиях.
Оператор in также можно использовать в условиях, например в операто-
ре if:
name = "Alice"
if 'A' in name:
print("The letter 'A' is in the name.")
else:
print("The letter 'A' is not in the name.")
Результат:
The letter 'A' is in the name.
Здесь мы проверяем, есть ли буква А в переменной name. Поскольку она
присутствует, выводится соответствующее сообщение.
Методы lower () и upper ()
Методы lower () и upper () [57] используются для преобразования строк
к нижнему и верхнему регистру соответственно. Это полезные инструменты
при работе со строками, особенно когда необходимо сравнить их независимо
от регистра или выполнить форматирование.
Примеры использования lower () и upper ()
1 Метод lower () преобразует все буквы в строке к нижнему регистру. Это
позволяет унифицировать строки, что особенно полезно в сценариях про-
верки или сравнения.
criginal_string = "Hello, World!"
lowercase_string = criginal_strir.g. lower () # Преобразуем все буквы
к нижнему регистру.
print(lowercase string) # Ожидаемый результат: "hello, world!"
Результат:
hello, world!
Enter a numbrnr: 5
The number 5 is odd.
Q original_string = "Hello, WorldI"
lowercase_string = original_string.lower() # Преобразуем все буквы к нижнему регистру,
print(lowercas«_string) • 0жида*»мй результат: “hello, world!"|
••• hello, world!
message "Hello, world!"
is_univers«_pr«sent 'universe' in message
W Проверяем, есть ли 'universe* в строке message.
print(is^universe^present) • Ожидаемым результат: False
False
name "Alice"
if 'A* in name:
print("The letter 'A' is in the name.")
else:
print(“The letter 'A' is not in the name.”)
The letter ‘A* is in the name.
original_string » "Helle, World!"
lowercasestring = original_string.lower() • Преобразуем асе буквы к нижнему регистру,
nrintf lower гача ч+гтпаТ В Оагиляемлй поаулктдтг "hello world!"
Рис. 4.15
В этом примере оригинальная строка "Hello, World!" была преобразована
к нижнему регистру и выведена на экран.
2. Метод upper () преобразует все буквы в строке к верхнему регистру. Это
может быть полезно, например, при выделении текста.
original_string = "Goodbye, World!"
uppercase string = original_string.upper()
# Преобразуем к верхнему регистру.
print(uppercase string) # Ожидаемый результат: "GOODBYE, WORLD!"
Результат:
GOODBYE, WORLD!
В данном случае строка была преобразована в верхний регистр и выведе-
на на экран.
3. Сравнение строк с учетом регистра.
Методы lower () и upper () могут использоваться для сравнения строк без
учета регистра:
user_input = "Python"
correct answer = "python"
# Используем lower() для сравнения
if user_input.lower() == correct_answer.lower():
print("Correct answer!")
else:
print("Try again.")
Результат:
Correct answer!
В этом примере пользовательский ввод сравнивается с правильным отве-
том, и оба значения приводятся к нижнему регистру для корректного сравне-
ния. Таким образом, программа не будет зависеть от регистра.
Логические операторы and и or
Логические операторы and и or [58] используются для выполнения логичес-
ких операций над выражениями и возвращают логическое значение True или
False. Они помогают комбинировать несколько условий, что позволяет пи-
сать более гибкий и эффективный код.
Оператор and
Оператор and возвращает True, только если оба выражения истинны. Если
хотя бы одно из выражений ложное, результат будет False.
Пример:
а = 10
b = 5
с = 15
if а > b and с > а:
print.("Both conditions are True.")
else:
print("At least one condition is False.")
Результат:
Beth conditions are True.
О • = 10
b = 5
c * * 15
if a > b and c > a:
print("Both conditions are True.")
else:
print("At least one condition is False.")
••• Both conditions are True-
message = "Hello, world!”
is_universe_present * ’universe’ in message
• Проверяем, есть ли 'universe' строке message.
print(is_universe_present) w Ожидаемый результат: False
False
01 name = "Alice”
if *A’ in name:
print("The letter ’A' is in the name.”)
else:
print("The letter 'A' is not in the name.")
The letter 'A' is in the name.
original_string = "Hello, World!"
lowercase_string = original_string.lower() # Преобразуем все буквы к нижнему регистру.
print(lowercase_string) 9 Ожидаемый результат: "hello, world!"
Рис. 4.16
В этом примере оба условия (а > Ьис > а) истинны, поэтому программа
выводит сообщение об этом.
Оператор or
Оператор or возвращает True, если хотя бы одно из выражений истинно. Если
оба выражения ложны, результат будет False.
Пример:
х = 7
У = 3
z = 10
if х > у or z < у:
print("At least one condition is True.")
else:
print("Both conditions are False.")
Результат:
At least one condition is True.
В данном случае одно из условий (х > у) истинно, поэтому программа
сообщает об этом.
Использование логических операторов в условиях
Лохические операторы можно комбинировать для создания сложных ус-
ловий:
аде = 25
has_licer.se = True
if age >= 18 ana has_license:
print("You can drive a car.")
else:
print ("You cannot drive a car.")
Результат:
You can drive a car.
Здесь мы проверяем два условия: возраст и наличие лицензии. Посколь-
ку оба условия истинны, программа сообщает, что человек может управлять
автомобилем.
Дополнения к логическим операторам and и or
1. Порядок операций.
Логические операторы имеют определенный порядок операций. Опера-
тор not (логическое отрицание) имеет высший приоритет, за ним идет and,
а в конце or. Это означает, что выражения будут вычисляться в следующем
порядке [59]:
♦ not (отрицание);
• and (и);
• or (или).
Например:
а = True
b = False
с = True
result = a or b and с
print(result) * * Ожидаемый результат: True
ф a True
b False
c = True
result = • or b and c
print(result) # Ожидаеюй результат: True
••• True
+ Код V—* + текст У
x 5
У ’ 0
result a (y != 0) and (x / у > 1)
# Второе выражение не будет выполнено.
print(result)
• Ожидаемый реаультат: False
False
х = 5
у = 0
result « (х > 0) or (у 1« 0 and (х / у > 1))
• Второе выражение не будет выполнено.
print(result)
* Ожидаемый результат: True
True
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9t 10]
Рис. 4.17
Здесь b и с будут вычислены первыми (результат False), а затем результат
объединится с а с помощью or, что возвращает True.
2. Короткое замыкание.
Логические операторы в Python используют механизм, называемый корот-
ким замыканием (short-circuit evaluation [60]). Это значит, что выполнение
выражения останавливается, как только становится очевидно, что результат
уже известен.
Для and выполнение прекращается, если одно из условий ложно, так как
итоговый результат не может быть истинным.
х = 5
у = О
result = (у != 0) and (х / у > 1)
# Второе выражение не будет выполнено,
print(result)
# Ожидаемый результат: False
Для or выполнение прекращается, если одно из условий истинно, так как
итоговый результат уже будет истинным.
х = 5
у = О
result = (х > 0) or (у != О and (х / у > 1))
# Второе выражение не будет выполнено.
print(result)
IF Ожидаемый результат: True
Использование в списковых выражениях
(list comprehensions)
Логические операторы также могут быть использованы в списковых выраже-
ниях для фильтрации данных [61]:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even and greater than five = [num for num in numbers if num % 2 == 0
and num > 5]
print(even and greater_tnar. five) # Ожидаемый результат: [6, 8, 10]
Объяснение:
1. Определение списка numbers. Создаем список numbers, который содер-
жит числа or 1 до 10.
2. Генератор списка.
even_and_greater_than_five = [num for num in numbers if num % 2 == 0
and num > 5]
Этот код использует генератор списка для создания нового списка. Мы
перебираем каждое num в списке numbers. Условие if num И == 0 and num
> 5 проверяет, четное ли число (остаток от деления на 2 равен 0) и больше
ли оно 5. Если оба условия выполняются, число добавляется в новый список
even_and_greater_than_f ive.
3. Вывод результата.
print (even and_greater thanfive) выводит на экран результат, который бу-
дет [6, 8, 10], так как именно эти числа удовлетворяют заданным условиям.
True
(J number! = fl, 2, 3, 4, 5, 6, 7, 8, у, ia]
even and greeter t han_f ive = [num for num in numbars if num % 2 == 0 and num > 5]
print(even and greater than five) # Ожидаемый результата [6, 8, 10]
(6, 8, 10]
ф username input("Введите ваше имя: ")
password input("Введите пароль: ")
if username == "admin" and password == "1234":
print("Доступ предоставлен.")
else:
print("Неправильное имя поль»ователя или пароль.")
Введите ваше имя: admin
Введите пароль: 1234
Доступ предоставлен.
for i in range(S): ft Итерируемся от 0 до 4 (всего S итераций).
print(i)
0
1
2
3
4
Рис. 4.18
В этом примере мы создаем новый список, который содержит только чет-
ные числа, превышающие 5.
Практический пример с пользовательским вводом
Логические операторы могут быть полезны в сценариях, где нужно прове-
рить несколько условий на основе пользовательского ввода:
username = input("Введите ваше имя: ")
password = input("Введите пароль: ")
if username == "admin" and password == "1234":
print("Доступ предоставлен.")
else:
print("Неправильное имя пользователя или пароль.")
(6, 8, 10]
О usernaee input("Введите вате имя “)
password input("Введите пароль: ")
if username == "admin" and password == "1234”:
print(“flocTyn предоставлен.")
else:
print("Неправильное имя пользователя или пароль.")
Введите вате имя: | ~~|
Q for i in range(5): • Итерируемся от 0 до 4 (всего 5 итераций).
print(i)
0
1
2
3
4
for i in range(2, 10, 2): # Начинаем с 2, заканчиваем на 10, ваг 2.
print(i)
Рис. 4.19
(6, 8, 10]
Q username = input ("Введите ваше имя: ’*)
password = input("Введите пароль: “)
if username *ж "admin" and password •• ”1234":
print("Доступ предоставлен.")
else:
print("Неправильное имя пользователя или пароль.")
• •• Введите ваше имя: admin_______________
Введите пароль: [1234 ~|
for i in range(S): # Итерируемся от 0 до 4 (всего 5 итераций).
print(i)
0
1
2
3
4
for i in range(2, 10, 2): « Начинаем с 2, аакакчиеаем на 10, таг 2.
print(i)
2
4
Рис. 4.20
(б, 8, 10]
ф username = input("Введите ваше имя: ")
password = input;(" Введи те пароль: “)
if username » "admin" and password "1234";
print("Доступ предоставлен.")
else:
print("Неправильное имя пользователя или пароль.")
• •• Введите ваше имя: admin
Введите пароль; 1234
Доступ предоставлен.
ф or i in range(S): • Итерируемся от 0 до 4 (всего 5 итераций),
print(i)
0
1
2
3
4
for i in range(2, 10, 2): • Начинаем c 2, заканчиваем на 10, шаг 2.
print(i)
2
4
Рис. 4.21
Этот код проверяет, соответствуют ли введенные имя пользователя и па-
роль заданным значениям. Если оба условия выполняются, доступ предостав-
ляется; если хотя бы одно из них ложное, выводится сообщение об ошибке.
Циклы
Циклы со счетчиком
Синтаксис в общем виде:
for счетчик in последсвательнссть:
# тело цикла, выполняемое на каждой итерации
Циклы со счетчиком используются в программировании для выполнения
операций по фиксированному количеству раз. В Python основной инстру-
мент для реализации циклов со счетчиком — оператор for, который позво-
ляет итерироваться по последовательностям, таким как списки, строки или
диапазоны чисел.
Цикл for
Цикл for [62] позволяет выполнять блок кода для каждого элемента в этой
последовательности. Один из наиболее распространенных способов его ис-
пользования — это итерация по числовым диапазонам с помощью функции
range().
Пример использования цикла for со счетчиком:
for i in range(5): ff Итерируемся от 0 до 4 (всего 5 итераций),
print(i)
Результат:
0
1
2
3
4
В этом примере цикл for выполняет блок кода 5 раз, а переменная i при-
нимает значения от 0 до 4.
1. Итерация с заданным начальным и конечным значениями.
for i in rar.ge(2, 10, 2): # Начинаем с 2, заканчиваем на 10, шаг 2.
print(i)
Результат:
2
4
6
8
Здесь мы указываем начальное значение 2, конечное значение 10 (не вклю-
чая его) и таг, равный 2.
2. Итерация по списку.
Цикл for может быть использован для перебора элементов в любом ите-
рируемом объекте, например, в списке:
vegetables = ("carrot", "potato", "cabbage"]
for vegetable in vegetables:
print(vegetable)
Результат:
carrot
potato
cabbage
0 vegetable* » ("carrot", “potato", "cabbage"]
for vegetable in vegetable*:
print (vegetable}]
••• carrot
potato
cabbage
for i in range(2, 8): # Генерирует числа от 2 до 7.
print(i)
2
3
4
5
6
7
0 for i in ranged, 10, 2): # Генерирует числа от 1 до 9 с вагон 2.
print(i)
1
3
5
7
9
for i in ranged, 0, ‘1): * Генерирует числа от 5 до 1.
Рис. 4.22
В этом примере цикл for проходит по каждому элементу списка fruits
и выводит его на экран.
Тело цикла
Рис. 4.23
Конструкция range ()
Функция range () [63] — это встроенная функция, которая генерирует пос-
ледовательность чисел. Она часто используется в циклах, таких как for, для
повторения определенных операций заданное количество раз. range () может
принимать от одного до трех аргументов: стартового значения, конечного
значения и тага.
Синтаксис:
range(start, stop[, step])
• start (необязательный) — начальное значение (включительно), по
умолчанию равно 0.
• stop (обязательный) — конечное значение (не включая его).
* step (необязательный) — шаг между значениями, по умолчанию равно
1.
Примеры использования функции range ()
1. Использование start и stop.
for i in range(2, 8): # Генерирует числа от 2 до 7.
print(1)
Здесь мы указываем начальное значение 2 и конечное значение 8 (не вклю-
чая его).
2. Использование шага.
for i in ranged, IC, 2): # Генерирует числа от 1 до 9 с шагом 2.
print(1)
б
7
A |for i in range(l, 10, 2): # Генерирует числа ст 1 до 9 с шагом 2.
print(i)
1
3
5
7
9
A for* i in rang»(5, 0, -1): • Генерирует числа от 5 до 1.
print(i)
... 5
4
3
2
1
+ Код + Текс1
Q numbers = list(range(l, 11)) # Создает список чисел от 1 до 10.
print(numbers)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evennumbers (i for i in range(29) if i % 2 0)
W Генерирует список четных чисел от 0 до 19.
Рис. 4.24
В этом примере range (1, 10, 2) создает последовательноегь начиная с 1
и увеличивая значение на 2 на каждой итерации.
3. Отрицательные значения.
Функция range () также поддерживает отрицательные значения и может
использоваться для итерации в обратном направлении:
for i in range(5, 0, -1): # Генерирует числа от 5 до 1.
print(i)
Здесь мы начинаем с 5, указываем конечное значение 0 (не включая его)
и указываем шаг -1.
4. Создание списков с помощью range().
Функция range () может использоваться для создания списков с помощью
приведения к типу list ():
numbers = list (ranged, И)) If Создает список чисел от 1 до 10.
print(numbers)
Результат:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
5. Комбинация с условиями.
range () полезен для создания сложных условий, например при фильтрации:
even numbers = [i for i in range(20) if i % 2 == 0]
ff Генерирует список четных чисел от 0 до 19.
print(even_numbers)
Результат:
[0, 2, 4, 6, 8, 10, 12, 14, i6, 18]
Операторы break и continue в цикле for
Операторы break и continue [64] используются для управления потоком вы-
полнения циклов и позволяют более гибко управлять их поведением, особен-
но в циклах for.
Оператор break
Оператор break используется для немедленного завершения цикла. Ког-
да break выполняется, цикл прекращается, и управление передается первой
строке после него.
Пример:
for 1 in range(10):
if i == 5:
break # Прерываем цикл, если i равно 5.
print(i)
for i in range(10):
if i X 2 0:
continue » Пропускаем текущую итерацию, если i четное.
print(i)
1
3
5
7
9
Q for i in range(10):
if i 3:
continue W Пропускаем 3
if i == 7:
break # Прерываем цикл на 7
print(i)
Рис. 4.25
В этом примере цикл for выполняется от 0 до 9, но будет прерван, когда i
станет равно 5. Следовательно, мы не увидим значений 5, 6. 7, 8 и 9 в выводе.
Оператор continue
Оператор continue используется для пропуска текущей итерации цикла
и перехода к следующей При его выполнении оставшаяся часть кода в теку-
щей итерации цикла не будет выполнена и выполнение перейдет к следую-
щей итерации.
Пример:
fcr i in range(10):
if i % 2 == 0:
continue # Пропускаем текущую итерацию, если i четное,
print (i)
В этом случае цикл for итерируется от 0 до 9, но, если i четное число, опе-
ратор continue пропускает выполнение строки print (i), и это приводит к то-
му, что в выводе остаются только нечетные числа.
Совмещение break и continue
Вы можете использовать оба оператора в одном цикле для более сложной
логики обработки:
fcr i in range(10):
if i == 3:
continue # Пропускаем 3
if i == 7:
break * Прерываем цикл на 7
print(i)
Цикл пропускает число 3 и завершается, когда переменная i достигает 7,
поэтому 7 и все числа после него не выводятся.
7
ф count @
while count < 5: * Условие: пока count мемъые 5
print(count)
count *« 1 # Увеличиваем значение count на 1
... 0
1
2
3
4
count = 0
while True: # Создаем бесконечный цикл
Рис. 4.26
Цикл while
Цикл while [65] используется для повторения блока кода до тех пор, пока за-
данное условие истинно. В отличие от цикла for, который обычно предна-
значен для итерации по последовательностям, он более гибкий, так как его
выполнение зависит от условия.
Синтаксис:
while условие:
ff Блок кода, который выполняется пока условие истинно
ложь 1 г 1 пока истина условие действие
Рис. 4.27
Пример использования цикла while, который выводит числа от 0 до 4:
count = О
while count < 5: # Условие: пека count меньше 5
print(count)
ccunt += 1 I Увеличиваем значение count на 1
В этом примере условие count < 5 проверяется перед каждой итерацией.
Как только ccunt становится равным 5, цикл завершается.
1. Операторы break и continue.
Цикл while можно комбинировать с операторами break и continue для бо-
лее сложного контроля выполнения.
Использование break:
ccunt = О
while True: # Создаем бесконечный цикл
if count == 5:
break * Прерываем цикл, когда count равно 5
print(count)
count += 1
В этом примере цикл while бесконечен (так как условие всегда истинно),
но с оператором break мы можем прервать его выполнение.
Использование continue:
count = С
while count < 5:
count += 1 fr Увеличиваем count на 1
if count == 3:
continue Пропускаем итерацию, когда count равнс 3
print(count)
Результат:
1
2
4
5
Здесь, когда count становится равным 3, оператор continue пропускает ос-
тавшуюся часть тела цикла и переходит к следующей итерации.
2. Переменные цикла и управление ими.
В цикле while важно правильно управлять переменными, чтобы избежать
бесконечных циклов. Например, если условие никогда не становится лож-
ным, цикл будет выполняться бесконечно, что может привести к зависанию
программы.
Бесконечный цикл (неправильное использование):
count = С
while count < 5:
print(count) # Забудьте об увеличении count
Этот цикл будет печатать 0 бесконечно, так как count не увеличивается
и условие count < 5 остается истинным.
3. Применение в задачах.
Цикл while часто используется в различных задачах:
• когда надо запросить пользовательский ввод:
response = ""
while response.lower() != "exit": # Работает, пека пользователь не вве-
дет "exit"
response = input("Введите 'exit' длч выхода: ")
когда надо обработать данные:
data = [1, 2, 3, 4, 5]
inaex = О
while index < len(data): # Итерируем по элементам списка
print(data L index])
index += 1
4. Сложные условия.
Цикл while также может использовать сложные условия. Например, ком-
бинировать их с помощью логических операторов and и or.
count = О
while count < 5 and count % 2 == 0: * Условие, которое будет истинно,
пока count меньше 5 и является четным
print(count)
count += 1
В этом случае цикл будет продолжаться, пока count меньше 5 и является
четным числом.
Выводы
В главе рассмотрены фундаментальные элементы синтаксиса Python, обеспе-
чивающие базовую логику и функциональность программ. Ниже — ключе-
вые итоги по основным блокам.
Арифметические операторы
Поддерживаются все базовые операции: сложение (+), вычитание (-), ум-
ножение (*), деление (/), целочисленное деление (//), остаток от деления (%),
возведение в степень (**).
Особенности:
Деление / всегда возвращает float, даже если операнды — int.
Целочисленное деление И отбрасывает дробную часть, сохраняя только
целую.
Остаток % полезен для проверки четности (х %2 ==О) или распределения
ресурсов (например, яблок по коробкам).
Возведение в степень позволяет извлекать корни (х **0.5 квадратный ко-
рень).
Приоритет операций; скобки -> унарные операторы (-, abs()) ->**->*, /, //,
%-»+,--» сравнения -» логические операторы -> присваивание (=).
Операторы присваивания
Базовый оператор = сохраняет значение в переменную.
Составные операторы (+=, -=, *=, !-> //-, %=, **=) комбинируют операцию
и присваивание (например, х += 5 эквивалентно х = х + 5).
Позволяют сократить код и повысить его читаемость при изменении зна-
чений переменных.
Работа со строками
Конкатенация: объединение строк через + или метод .join () (эффективен
для множества строк).
Форматирование:
f-строки (f"Текст {переменная}") — современный и удобный способ встав-
ки значений.
Метод . format () и оператор % — устаревшие, но еще встречающиеся аль-
тернативы.
Повторение строк: * (например, «Hi! * 3 -Э «HiHiHi»).
Длина строки: функция 1еп () возвращает количество символов.
Регистр методы .lower () и .upper (} преобразуют строку к нижнему/верх-
нему регистру (полезны для сравнения без учета регистра).
Типы данных и преобразование
Python — язык с динамической типизацией: тип переменной определя-
ется значением.
Основные типы
int — целые числа (например, аде = 25).
float — числа с плавающей точкой (даже 22.0 — это float).
str — текстовые данные (например, name = «Анна»).
Проверка типа: функция type () (например, type(age) cclass ‘int’>).
Преобразование типов- функции int(), float(), str() (например,
int(«199»)-> 199).
Важное правило: при арифметических операциях с разными типами Python
автоматически приводит результат к float, если хотя бы один операнд — float.
Операторы сравнения
Возвращают булевы значения (True/False):
> (больше), >= (больше или равно), < (меньше), <= (меньше или равно), ==
(равно), != (не равно).
Используются в условиях (if, while) и логических выражениях.
Пример: 5 > 3 -> True, “abc” == *abc” -Э True.
Логические опера торы
and — истинно, если оба условия истинны
or — истинно, если хотя бы одно условие истинно.
not — отрицание (высший приоритет).
Особенности:
Порядок выполнения: not -э and -э or.
Короткое замыкание: Python прекращает вычисление, как только резуль-
тат ясен (например, в False and X второй операнд не вычисляется).
Примеры:
(х > 5) and (у < 10) — оба условия должны быть истинны.
(а == 1) or (b == 2) — достаточно одного истинного условия.
Оператор членства in
Проверяет наличие элемента в последовательности (строка, список, кор-
теж и т. д.).
Возвращает True/False.
Пример: "a” in “apple” -> True, 3 in [1, 2,4] -> False.
Циклы
for: итерация по последовательностям (списки, строки, range ()).
Синтаксис: for элемент in коллекция: ....
Пример: for i in range (5): print (i) выводит числа от 0 до 4.
while: выполнение, пока условие истинно.
Синтаксис: while условие: ....
Важно: вручную изменять переменные в условии, чтобы избежать беско-
нечного цикла.
Управление циклами:
break — выход из цикла.
continue — пропуск текущей итерации.
ranged : генерирует числовые последовательности.
Аргументы: start, stop, step (по умолчанию 0, 1).
Примеры: range(2, 10, 2) -> 2,4, 6, 8.
Правила именования переменных
Допустимы: буквы, цифры, _ (но не в начале).
Нельзя использовать ключевые слова Python (print, if и т. п.).
Рекомендации:
Имена должны быть понятными и отражать смысл (например, user age,
а не х).
Использовать подчеркивания для разделения слов (total_price).
Избегать слишком коротких или абстрактных имен.
Общий вывод
Освоенные конструкции — основа программирования на Python:
Арифметические и логические операторы позволяют выполнять вычисле-
ния и принимать решения.
• Типы данных и их преобразование обеспечивают гибкость работы
с информацией.
• Циклы и условия структурируют выполнение кода.
• Строковые операции и форматирование упрощают работу с текстом.
Правильное применение этих инструментов гарантирует:
• читаемость и ноддерживаемость кода; точность вычислений;
♦ эффективное управление потоком выполнения программы.
Глава 5
Структуры данных в Python
Строки
Строки — это один из основных типов данных в Python, используемый для
хранения текстовой информации. Они позволяют работать с именами, ад-
ресами, сообщениями и др. Давайте подробно рассмотрим свойства строк
и методы работы с ними.
Создание строк
Строки [бб] могут быть созданы с использованием одинарных (<... >),
двойных ("...") или тройных кавычек .."""). Тройные ка-
вычки позволяют создавать многострочные строки, что может быть полезно
для больших текстов или многострочных комментариев.
Пример:
single_quote_string = 'Hello, World!'
double_quore_string = "Hello, World!"
multi line_strir.g = """This is a
multi-line string."""
Доступ к символам строки
Строки — это последовательности символов, и можно получить доступ
к отдельным символам, используя индексы, которые начинаются с 0.
Пример:
greeting = "Hello"
first character = greetingl'] * 'H'
last_character = greeting(-1] ff 'o'
Срезы строк
Python позволяет использовать срезы (slicing) для извлечения подстрок.
Срез осуществляется с помощью квадратных скобок и двоеточия (:).
Пример:
text = "Hello, World!"
substring = text[0:5] fr 'Hello'
substring_from_start = text[:5] # 'Hello'
substring tc_end = text[7:] # 'World!'
Конкатенация и повторение строк
Вы можете объединять (конкатенировать) строки с помощью оператора +
и повторять их с помощью оператора *.
Пример:
string! = "Hello"
string2 = "World"
combined = string! + " " + string2 # 'Hello World'
repeated = string! * 3 # 'HelloHelloHello'
Изменяемость строк
Строки в Python неизменяемы (immutable), значит после создания строки
нельзя изменить ее содержимое. Однако можно создать новую строку на ос-
нове существующей.
Пример:
original = "Helle"
# Попытка изменить первый символ вызовет ошибку:
# original [0] = 'h' if Это вызовет ошибку ТуреЕггог
# Вместо этого создаем новую строку
new_string = 'h' + original[1:] # 'hello'
Форматирование ст рок
Python предоставляет несколько способов форматирования строк. Самые
популярные — это использование метода str. format () и f-строки.
Пример с использованием str. format ():
name = "Alice"
age = 30
formatted_string = "My name is {} and I am {} years old.".format(name,
age)
Пример с использованием f-строк (Python 3.6 и выше):
formattedstring = f"My name is {name} and I am {age} years eld."
Методы ci рок
Python предоставляет множество методов для работы со строками. Вот
некоторые из наиболее полезных:
• .lower() и .upper{) преобразуют строки в нижний или верхний ре-
гистр:
text = "Helle"
print(text.lower()) # 'hello'
print(text.upper()) # 'HELLO'
• .replace (old, new) [67] заменяет все вхождения подстроки old на под-
строку new:
подстрока, которую
нужно заменить
исходная строка, в которой ' ъ подстрока, на которую
будет производиться замена \ нужно заменить old
string.replace(old, new, count=None)
(необязательный) — это максимальное
количество замен, которые нужно
произвести. Если не указано, все
вхождения old будут заменены на new
text = "Hello, World!"
new_texr = text.replace("World", "Python") # 'Hello, Python!'
• .split (delimiter) разделяет строку на подстроки по заданному разде-
лителю:
text = "Hello,World,Python"
words = text.split(",") # ['Hello', 'World', 'Python']
• . join (iterable) объединяет элементы из итерируемого объекта (на-
пример, списка) в строку, используя ее как разделитель:
words = ['Hello', 'World', 'Python']
result = ", ".join(words) # 'Hello, World, Python'
Поиск в строках
Методы поиска подстрок в строках:
• . find (substring) [68] возвращает индекс первого вхождения подстро-
ки или -1, если она не найдена.
исходная строка, в которой
ищется подстрока
(необязательный) — индекс,
до которого ведется поиск
(по умолчанию длина строки)
string.find(sub, start=0, end-len(string))
искомая подстрока
(необязательный) — индекс,
с которого начинается поиск
(по умолчанию 0)
text = "Hello, World!"
index = text.find("World") # 7
.count(substring) [69] возвращает количество вхождений подстроки
в строке.
исходная строка или
последовательность, в которой
мы будем производить подсчет
подстрока или элемент,
который мы хотим найти
и подсчитать
(необязательный) — это начальный
индекс, с которого мы начинаем
поиск. Если этот параметр
не указан, поиск начинается
с самого начала строки
number-search here.count(find me, sart, end)
(необязательный) — это
конечный индекс, до которого
мы ведем поиск. Если этот
параметр не указан, поиск
производится до конца строки
text = "Helle, World! Hello!"
count = text.count("Hello") # 2
Метод . strip () [70] — это функция, которая нужна для удаления пробе-
лов и других символов (по умолчанию пробелов) из начала и конца строки.
Этот метод очень полезен в ситуациях, когда вам нужно очистить строку от
лишних пробелов, которые могут быть случайно добавлены при вводе или
обработке текстовых данных.
Синтаксис:
str.strip([chars])
• chars (необязательный аргумент). Строка, содержащая символы, кото-
рые необходимо удалить. Если этот аргумент не указан, то по умолча-
нию будут удалены пробелы (включая пробелы, табуляцию и символы
новой строки).
исходная строка,
из которой будут
удалены символы
string.strip([chars])
(необязательный) — это строка, содержащая
символы, которые нужно удалить. Если этот
параметр не указан, метод strip () будет
удалять только пробельные символы
(пробелы, табуляции, переводы строк и т. д.)
Пример использования метода . strip ():
text = " Hello, World! "
cleaned_text = text.strip()
print(cleaned_text) # 'Hello, World!'
В этом примере strip () удаляет пробелы, которые находятся в начале
и в конце строки text.
Удаление специальных символов
Вы также можете передать строку, содержащую специальные символы,
которые хотите удалить. Например:
text = "—Hello, World!—"
cleaned_text = text.strip!)
print(cleaned_text) # 'Hello, World!'
Здесь strip (< - >) удаляет символы «—» с обеих сторон строки.
Индексы и срезы строк
Индексы и срезы — это мощные инструменты для работы со строками
в Python. Они позволяют получать доступ к отдельным символам строки
и извлекать подстроки. В этом разделе мы подробно рассмотрим, как исполь-
зовать индексы и срезы, а также приведем оригинальные примеры.
Индексы строк
Как мы уже выяснили, строки в Python — это последовательности симво-
лов, и каждый символ имеет свой индекс [71]. Индексация начинается с нуля,
что означает, что первый символ строки имеет индекс 0, второй — 1, и т. д. Вы
можете использовать отрицательные индексы, чтобы обращаться к символам
с конца строки. Например, -1 соответствует последнему символу, -2 — пред-
последнему, и т. д.
Примеры:
text = "Hello, World!"
if Положительные индексы
first character = text 10] # 'H'
second_character = text[l] 4 'e'
last_character = text[12] # '!'
# Отрицательные индексы
last_character_neg = text[-l] I '!'
second last character_neg = text[-2] # 'd'
print(first character) * 'H'
print(second character) # 'e'
print(last_character) # '!'
print(last character neg) # '!'
print(second_last_character_neg) f 'd'
о
ф # Глава 5
text = "Hello, World!"
w Положительные индексы
first_character = text[0] ff * *H*
second_charact€r « text(l] # *e'
last_character text[12] # '!'
9 Отрицательные индексы
last_character_neg = text[=l] # ’!’
second_last_character_neg text( 2) # 'd'
print(first_character) * ‘H’
print(second_character) # *e‘
print(last_character) #
print(l»*t_character_neg) • *!'
print(seco*id_la*t_charact*r_neg) 9 'd‘
H
e
!
!
d
text = "Hello, World!"
9 Срез от 0 до $ (символы с индексами от 0 до 4)
Рис. 5.1
Срезы строк
Срезы позволяют извлекать подстроки, определяя начальный и конечный
индекс с помощью двоеточия Срез возвращает новый объект строки, кото-
рый включает символы на указанных позициях.
Синтаксис:
substring = string|start:end]
• start — индекс, с которого начинается срез (включается);
• end — индекс, на котором срез заканчивается (не включается);
• если start опущен, то по умолчанию используется 0;
• если end опущен, то по умолчанию используется длина строки.
Примеры:
text = "Hello, World!"
< Срез от 0 до 5 (символе с индексами от 0 до 4)
substringl = text[0:5] # 'Hello'
print(substringl)
# Срез ст 7 дс 12 (символы с индексами от 7 до 11)
substring2 = text[7:12] # 'World'
print(substrings)
s Срез от начала до 5
substrings = text[:5] # 'Hello'
print(substrings)
ff Срез от 7 до конца
substring4 = text[7:] т 'World!'
print(substring4)
# Срез от начала дс конца
substrings = text[:] > 'Helle, World!'
print(substrings)
f Срез с использованием отрицательных индексов
substrings = text[-6:-l] # 'World'
print(substrings)
# Срез с шагом
substring7 = text(::2] # 'Hlc ol!'
print(substring7) а Каждый второй символ
(j text - “Hello, wtj'ldi*
• Срез or 0 до S (cineo» с индексами от 0 до 4)
substrlngi - t«xt[e:5] • 'Hello'
prlnt(substrlngl)
• Срез от 7 до 12 (символы с индексами от 7 до 11)
substring? - text(7:12] 9 World'
print(substring?)
• Срез от м«м»л» до 5
substring) • t«xt(:5] 9 *н»По'
print(substring))
• Срез от 7 до KtMja
substrlng4 • text(7:) > 'WorldI"
print (substring^
* Срез от начала до конца
substrings - text(:J • 'Hello, world!*
prlnt(substrlngS)
Срез с мсполнзоммием отрицательных индексов
substrings text(-6:-l] World'
print(substrlng6)
• Срез с вагон
substring? - text(::2) • 'Hlo oil'
print (substring?) » Каждой второй сю«ол
~ Hello
World
Hello
world!
Hello, world!
World
Hlo oil
Рис. 5.2
Шаги в срезах
Вы также можете указывать шаг с помощью третьего параметра.
Синтаксис [72]:
substring = strinq|start:end:step]
step определяет, как перемещаться по строке. Положительное значение
означает движение вперед, отрицательное — назад.
Пример:
text = "Hello, World!"
# Получение подстроки с шагом 2
every second_char = text[::2] # ’Hlo ol!'
print(every second char)
# Получение подстроки с шагом -1 (резеро строки)
reversed_text = text[::-l] # ‘SdlroW ,olleH'
print(reversed_text)
t Получение подстроки от 7 до конца с шагом 2
substring_with_step = text[7::2] # 'Wr!'
print(suostring with step)
Изменяемость строк
Важно помнить, что строки в Python неизменяемы (immutable). Невозможно
менять строку напрямую. Однако можно использовать индексы и срезы для
создания новых строк.
Пример:
text = "Hello, World!"
# Попытка изменить первый символ строки вызовет ошибку
# text[0] = 'h' # TypeErrcr: 'str' object does not support item
assignment
if Вместо этого создаем нсвую строку
new_text = 'h' + text[1:J # 'hello, World!'
print(new text)
JdlroH ,olleH
wrd
Q text - "Hello, World Ij
w Попытка изменить первый символ строки вызовет оимбку
9 text[e] "h* • TypeError; ’str' object does not support Itee assignment
• Вместо этого создаем новую строку
new_text - *h* ♦ text(l:] • 'hello. World Г
prlnt(new_text)
••• hello. World!
Q text "Hello, World 1"
length - len(text) * 13
print(length)
— 13
9 Пустой словарь
y_dlct - {}
в Словарь с начальной инициализацией
y_dict - {
’ключ!’: знамение!’,
клвч2‘: ‘значение?*,
’ключу; ’значение?’,
}
exanple_dlct - {
’age’: 3$,
height’s 1.75
)
exaeple.dict - {
Длина строки
Вы можете использовать встроенную функцию 1еп () [73] для определения
длины строки:
text = "Hello, World!"
length = len(text) ? 13
print(length)
Индексы и срезы — это важные механизмы для работы со строками
в Python. Они позволяют легко получать и манипулировать отдельными сим-
волами и подстроками (табл. 5.1).
Табл. 5.1
Тема Описание Синтаксис Пример Пояснение
Индексы Индексы использу- ются для доступа к отдельным симво- лам строки. Индекса- ция начинается с 0 st ring[index] text = "Hello" text[0] 1 'H' text[-l] * 'o' Используйте ин- дексы для получе- ния конкретных символов
Доступ к символу Используйте поло- жительные или отри- цательные индексы, чтобы получить нужный символ string[index] text[2] f '1' text[-2] # '1' Каждому символу соответствует свой индекс
Срезы Срезы извлекают подстроки. Формат- string(start:end] string (start:end] text(0:S) < 'Hello' Позволяет полу- чить часть строки между двумя индексами
Срез от начала Если start опущен, начинается с 0 string!:end] text(:5] ♦ 'Hello' Полезно для из- влечения первых символов
Срез Де конца Если end опущен, за- канчивается в конце строки string (start:) text [7:] * 'World!' Удобно для извле- чения символов от определенного индекса до конца строки
Отрица- тельные индексы при срезах Отрицательные индексы могут быть использованы для извлечения симво лов с конца строки string [startrend] text[-6:-l] 3 'World' Позволяет по- лучать символы от конца строки, используя отрица- тельные значения
Шаги Формат: string (start:end:step. Поз- воляет пропускать символы string[start; end:step) text[::2] # 'Hlo oil' Полезно для выбора символов с определенным шагом в строке
Тема Описание Синтаксис Пример Пояснение
Шаг с отрица- тельным значением Шаг может быть от- рицательным. чтобы получить строку в обратном порядке stringfstart: end:step] text[::-l] * 'idlroW ,olleH' Используется для реверса строки
Длина строки Для определения длины строки ис- пользуйте функцию 1ег.() len(string) len. (text) » 13 Определяет коли- чество символов в строке
Изменяе- мость Строки — неизме- няемые объекты. Невозможно изме- нить их содержимое напрямую N/A new text = 'h' + cext[l:] i 'hello' Для изменения строки создается новая строка на основе существу- ющей
Словари
Словарь [74] — это неупорядоченная коллекция пар «ключ-значение», ко-
торая позволяет хранить данные в удобном формате для быстрого доступа.
Ключи в словаре уникальны и используются для получения соответствую-
щих значений. Словари — изменяемые (мутируемые) объекты, значит, мож-
но добавлять, удалять и изменять элементы.
Создание словарей
Существуют несколько способов создания словарей.
Использование фигурных скобок
Синтаксис:
# Пустой словарь
my_dict = {}
# Словарь с начальной инициализацией
my_dict = {
'ключ!': 'значение!',
'ключ2': 'значение?',
'ключЗ': 'значение?',
}
В этом примере мы создаем словарь с тремя ключами и значениями.
Компоненты словаря:
• Ключи должны быть уникальными и неизменяемыми (например, стро-
ки, числа или кортежи).
• Значения могут быть любого типа, включая другие структуры данных
(например, списки, другие словари и т. д.).
В Python словари позволяют использовать значения различных типов
данных.
Возможные типы значений в словаре:
1. Числа — целые (int) или с плавающей запятой (float).
example_dict = {
'age': 30,
'height': 1.75
}
2. Строки в качестве значений.
example diet = {
'name': 'Иван',
'city': 'Москва'
}
3. Булевы значения — логические значения True или False.
example_dict = {
'is_student': True,
'is employee': False
4. Списки, которые могут содержать несколько элементов.
example diet = {
'fruits': ['apple', 'tree', 'fox']
5. Кортежи как значения.
example_dict = {
'coordinates': (10.5, 20.3)
}
О exaeplt_dlct - |
'i*_itvdenf: True,
'is employee*: False
J
exaaple.dlct • (
•fruits': ('apple'. 'tree', *<«’]
}
Q «xMpl«_dlct - (
'coordinates': (IB.5. je.l)
}
exa^>le_dlct • (
‘unlque.nuabers*: (I, 2» I» 4, 5}
}
exaeple.dlct - {
person': {
'naw';
'age': 22
’Jeb': 'developer'
}
def greet(лама):
returr /"Hello. (naee}!“
exaapie_dlct • (
' greet lng_fw*ct Ion': greet
Рис. 5.4
6. Множества (sec) в качестве значений.
example_dict = {
'unique_numbers': {1, 2, 3, 4, 5}
}
exaopla_dlct - (
•coordinate»': ie.1)
© exaeple_dlct -
unlque_ni^>ers': (I, 2, 3, 4, 5}
^«xpaplejHct • {
'person': {
‘нам*: "Ламе*,
•С*': 22
'Job's 'developer'
def greet(ламе):
return f"Mello.
exeeple.dlct <
' greet lng_funct loo ‘ greet
Q print(exMple.dlctf'freeting_f«nctlon’K'MapW)) • Вырод: Hello, Марам!
— Hello, меры al
nixed dlct - {
'new': "He**'.
•ge’: M,
'Is_*todent': Falie,
'grades': [Sb, 8S, 75],
address': (
’city’: MocKP*',
'street': 'Денина'.
Рис. 5.5
7. Другие словари, что позволяет создавать вложенные структуры.
example_dict = {
'person': {
'name': 'Анна',
'age': 22
},
'job': 'developer'
}
В коде мы видим создание словаря с именем example diet, который содер-
жит информацию о человеке и его профессии.
Объяснение:
1. Корневой словарь example dict — это главный словарь, который содер-
жит две ключевых пары: <person > и ' job'.
2. К ключу 'person' привязан вложенный словарь, который хранит ин-
формацию о человеке. Внутренний словарь содержит следующие данные:
• ключ < патте > ассоциирован со значением <Анна>, значит, имя челове-
ка — Анна;
• ключ <аде> ассоциирован со значением 22, что указывает на возраст
человека.
3. Ключ 'job' связан со значением < developer >, что обозначает профессию
человека. В данном случае профессия — разработчик.
Итоговая структура
Таким образом, example diet представляет собой словарь, который содер-
жит информацию о человеке (в виде вложенного словаря) — Анна, 22 года —
и профессию — разработчик.
Визуальное представление
Структуру можно представить следующим образом:
examplejlict
— 'person' (вложенный словарь)
— 'name': 'Анна'
I— 'аде': 22
— 'job': 'developer'
Использование вложенных словарей позволяет организовывать данные
более структурированным образом, что упрощает управление и доступ. Мы
можем легко получить информацию как о самом человеке, так и о его про-
фессии, используя соответствующие ключи.
8. Функции.
def greet(name):
return f"Hello, {name}!"
example diet = {
'greeting function': greet
Использование функции из словаря:
print(example diet['greeting^function']('Мария')) # Вывод: Hello, Мария!
}
exaaple_dict - {
’person’: {
'паве': ’Анна',
'age': 22
},
'job': ‘developer’
© def greet(паве):
return f"Hello, {паве}!'
exaepledict • {
'greeting-function': greet
© prir|t(exaaple_dict['greeting-function']('Мария')) * Вывод: Hello, Мария!
••• Hello, Мария!
•ixeddict - {
'паве': ‘Иван*,
’age’: 39,
'ls_student': False,
"grades': [98, 85, 75J,
’address': {
’city': 'Москва',
’street’: ’Ленина',
’nunber’s 15
}.
’height': 1.80,
* favorite_colors'; {'красный', 'синий', 'аелемый'},
'preferred-language': None,
greet_functior': greet • Вуккцмя greet из предыдущего примера
Пример словаря с разными тинами значений:
mixed_dict = {
'name': 'Иван',
'age': ЗС,
'is_student': False,
'grades': [90, 85, 75],
'address': {
'city': 'Москва',
'street': 'Ленина',
'number': 15
},
'height': 1.80,
'favcrite_colors': {'красный', 'синий', 'зеленый'},
'preferred-language': None,
'greet_function': greet f Функция greet из предыдущего примера
print(mixed_dict)
Объяснение:
1. 'name': 'Иван',.
Ключ < name > хранит строковое значение < Иван >, то есть имя человека.
2. 'аде': 30,.
Ключ < аде > хранит целое число 30, которое указывает на возраст человека.
3. 'is_student': False,:.
Ключ < is student > хранит логическое значение False. Эго может означать,
что Иван не является студентом.
4. 'grades': [90, 85, 75],:.
Ключ < grades > ассоциирован со списком [90, 85, 75], который содержит
оценки Ивана. В нем можно хранить несколько значений.
5. 'address': {:.
Ключ < address > хранит вложенный словарь с информацией об адресе че-
ловека.
6. 'city': 'Москва',:.
Этот ключ хранит строку < Москва >, обозначая город, в котором живет
Иван.
7. 'street': 'Ленина',:.
Ключ < street > хранит строку < Ленина >, которая указывает название улицы.
8. 'number': 15:.
Ключ < number > хранит целое число 15, которое указывает номер дома.
9. 'height': 1.80,
Ключ < height > содержит число с плавающей запятой 1.80, которое указы-
вает рост Ивана в метрах.
10. 'favorite colors': {'красный', 'синий', 'зеленый'},:.
Ключ < favorite colors > хранит множество (set) с тремя значениями:
'красный', 'синий' и 'зеленый', называя любимые цвета Ивана. хМножество
использует фигурные скобки и не допускает дублирования значений.
11. 'preferred^language': None,:.
Ключ < preferred_lar.guage > хранит значение None, что может означать, что
у Ивана нет предпочтительного языка.
12. 'greet_function': greet ₽ Функция greet из предыдущего примера.
Ключ < greet_function > ассоциирован с функцией greet, которая была оп-
ределена ранее. Это значит, что словарь может хранить не только данные, но
и функции, позволяя вызывать их позже через этот ключ.
Расшифровка результатов словаря:
'name': 'Иван',
'аде': 30,
'is_student': False,
'grades': [90, 85, 75],
'address': {
'city': 'Мссква',
'street': 'Ленина',
'number': 15
),
'height': 1.8,
'favorite_colors': {'красный', 'зеленый', 'синий'},
'preferred_language': None,
'greet_function': <function greet at лх7е5Ье48а94еС>
Объяснение:
1. 'name': 'Иван'.
Этот элемент представляет имя человека. Ключ < name > содержит строку
<Мван >, то есть человека зовут Иван.
2. 'аде': 30.
Ключ < аде > хранит целое число ЗС, которое обозначает возраст Ивана.
3. 'is student': False.
Здесь ключ <is student > ассоциирован со значением False. Это значение
указывает на то, что Иван не является студентом.
4. 'grades': [99, 85, 75].
Ключ < grades > хранит список [90, 85, 75]. Это означает, что у Ивана есть
три оценки: 90, 85 и 75.
5. 'address': {'city': 'Москва', 'street': 'Ленина', 'number': 15}.
Ключ < address > содержит вложенный словарь, который указывает на ад-
рес Ивана. Он состоит из грех частей:
• 'city': 'Москва': город — Москва.
• < street >: < Ленина >: улица — Ленина.
• < number >: 15: номер дома — 15.
6. 'height': 1.8.
Ключ < height > хранит значение 1.8, которое указывает рост Ивана в мет-
рах.
7. 'favorite colors': {'красный', 'зеленый', 'синий'}.
Ключ < favorite colors > хранит множество (set) из трех строковых значе-
ний: 'красный', 'зеленый', 'синий'. Это означает, что любимые цвета Ивана —
красный, зеленый и синий.
8. 'preferredlanguage': None.
Ключ 'preferred language' содержит значение None. Это говорит о том,
что у Ивана нет предпочтительного языка или он нс определен.
9. 'greet_function': <function greet at 3x'Je5be48a94el>.
<function greet at 0x7e5be48a94e0> указывает на то, что в памяти но ука-
занному адресу находится функция greet. Эта функция может быть вызвана
позднее через словарь с помощью ключа 'greet function'.
Результат показывает структуру и содержимое словаря mixed_dict. Он
иллюстрирует, как словари в Python могут объединять различные типы дан-
ных — строки, числа, логические значения, списки, вложенные словари, мно-
жества и функции — в единую структуру.
Пример:
# Словарь с разными типами значений
mydict = {
'имя': 'Анна',
'возраст': 25,
'город': 'Москва',
'баланс': 1С00.5С,
'покупки': ['яблоко', 'банан', 'веда'],
}
Создать словарь можно также с помощью функции diet (), которая позво-
ляет удобно задавать ключи и значения в виде именованных аргументов.
Синтаксис:
my_dict = diet(ключ!-значение1, ключ2=значение2, ключЗ=значениеЗ)
Пример:
animal_dict = diet(собака=3, кошка=4, попугай=2) # Ключи задаются как
именованные аргументы
Объяснение:
— Ключи:
• < собака > указывает на количество собак;
• 'кошка' указывает на количество кошек;
* 'испугай' указывает на количество попугаев.
— Значения:
• 3 — количество собак;
♦ 4 — количество кошек;
• 2 — количество попугаев.
Примечание. Использование функции diet () — удобный способ быстро
создавать словари, когда необходимо работать с заранее известными ключа-
ми и значениями.
Можно также создать пустой словарь и заполнить его позже:
emcty_dict = {} # Пустой словарь
Можно создать словарь, преобразуя список кортежей с помощью функ-
ции diet ().
Синтаксис:
ir.y_dict = diet(список_кортежей)
Рассмотрим пример, в котором преобразуем список кортежей, содержа-
щих названия книг и их количество на складе:
book list = [("1984", 10), ("Убить пересмешника", 5), ("Мастер и Мар-
гарита", 8)]
my_dict = diet(book_list)
3, 85, 75), ’address': {'city': Москва', ’street'. ’Ленина', 'nueher': IS), height': 1.8, ’favorite.colors’: {’зеленый’, красный’
• Словарь с разными типами значений
y_dict - {
’имя': ’Анна*,
'возраст': 2S,
'город': 'Москва',
'баланс': 1066.56,
'покупки': ['яблоко', ’банам’, 'вода'],
)
aniealdict dlct{собака-3, ковка-4, попугай«2) 9 Клони задаются как именованные аргументы
0 book—list - [("1684", 10), ("Убить пересмешника”, 5), "Мастер и Маргарита”, 8,)
y_dict - dict(book_list^
*tudent_grade* - {
"Алина": 4.5,
“Максим": 3.8,
"Екатерина”: 5.®
}
print(*tudent-grade*["максим"])
з.а
anlBal_count {
"собака": 3,
"кот": 5,
"попугай": 2
Рис. 5.7
Объяснение
Каждый кортеж в списке book_list содержит название книги и соот-
ветствующее число, которое указывает количество копий, хранящихся на
складе.
Первый кортеж ("1984", 10) означает, что на складе есть 10 экземпляров
книги «1984».
Второй кортеж ("Убить пересмешника", 5) говорит о наличии 5 экземпля-
ров книги «Убить пересмешника».
Третий кортеж ("Мастер и Маргарита", 8) показывает, что на складе 8 эк-
земпляров «Мастера и Маргариты».
Примечание. В этом случае мы успешно преобразуем список кортежей
в словарь, где каждый кортеж содержит пару ключ (название книги) и соот-
ветствующее значение (количество книг). Так мы получаем удобный доступ
к информации о количестве книг на складе.
К элементам словаря можно получить доступ, используя их ключи.
Синтаксис:
значение = my diet[ключ]
Допустим, у нас есть словарь, который хранит информацию о студентах
и их оценках:
student grades = {
"Алина": 4.5,
"Максим": 3.8,
"Екатерина": 5.0
Чтобы узнать оценку студента по имени, можно сделать следующее:
print(student_grades["Максим"]) # Выводит: 3.8
Объяснение
Ключом является имя студента — "Максим". Используя доступ по ключу,
мы можем получить соответствующее значение, которое в данном случае яв-
ляется оценкой 3,8.
Таким образом, доступ к элементам словаря осуществляется через ключи,
что позволяет легко извлекать значения, связанные с конкретными ключами.
Уникальность ключей в словаре
Ключи в словарях должны быть уникальными. Если вы попытаетесь до-
бавить новый элемент с уже существующим ключом, его значение будет пе-
резаписано.
Синтаксис:
my_dict[ключ] = новое_значение
Представим, что у нас есть словарь, который хранит информацию о раз-
личных видах животных и их количестве:
animal_count = {
"собака": 3,
"кот": 5,
"попугай": 2
Чтобы обновить количество собак, мы можем сделать следующее:
animal count("собака"] = 7 # Обновляет значение ключа "собака" на 7
print(animal_ count)
# Выводит: {'собака': 7, 'кот': 5, 'попугай': 2}
Объяснение
В данном случае ключом является "собака". После выполнения операции
обновления значение по этому ключу изменится с 3 на 7.
Таким образом, уникальность ключей в словаре обеспечивает отсутствие
дубликатов, и при попытке изменить значение для существующего ключа оно
перезаписывается.
Методы словаря
Метод рср () [75] удаляет элемент по указанному ключу и возвращает его
значение. Если ключ отсутствует, возникает ошибка.
Синтаксис:
значение = my diet.pop(ключ)
Пример
Допустим, у нас есть словарь, который хранит информацию о машинах
и их количестве:
car_inventcry = {
"Toyota": 5,
"Honda": 3,
"Ford": 4
value = car inventory.pep("Honda") # Удаляет "Honda" и возвращает его
количестве
print(car inventory) # Выводит: {'Toyota': 5, 'Ford': 4}
print(value) I Выводит: 3
Метод clear О [76] удаляет все элементы из словаря, оставляя его пустым.
Синтаксис:
my_dict.clear()
Пример
Используя тот же словарь car_inventcry, мы можем очистить его:
car_inventory.clear()
print(car_inventory) # Выводит: {}
Метод keys () [77] возвращает объект типа dict_keys, который содержит
все ключи словаря.
Синтаксис:
keys = my_dict.keys()
Пример
Используя словарь car_inventory, мы можем получить все ключи:
car_inventory = {
"Toyota": 5,
"Ford": 4
keys = car_inventory.keys()
print(keys) # Выводит: diet keys(['Toyota', 'Ford'])
car_ inventory - {
"Toyota": 5,
Ttonda": 3,
"Ford": 4
}
value - car_inventory.pop(*Honda") а Удаляет "Honda" *» возвращает его количество
prlnt(car_inventory) в Выводит: {'Toyota': 5, 'Ford': 4)
print(value) а Выводит; э
{'Toyota' 5, ‘Ford*: 4}
3
car_inventory.clear()
print(cer_lnvantory) • Выводит: {}
{)
0 c*r_inventory - Id
"Toyota": 5,
"Ford": 4
s
keys - car_inventory.keys()
prlnt(keys) • Выводит: diet JkeysQ'Toyota', 'Ford'])
•- dlct_keys(['Toyota', ‘Ford*])
values - car_lnventory.values()
print(v*lues) а Выводит: dlct_values([5, 4])
dlct_values([5, 4])
country_populatIon - {
"России": 145912B25,
"СИЛ": 331W265t,
Рис. 5.8
Метод values () возвращает объект типа dict_values, который содержит
все значения словаря.
Синтаксис:
values = my_dict.values()
Пример
Используем гот же словарь car_inventory, чтобы получить все значения:
values = car_inventory.values()
print(values) i Выводит: dict_values([5, 4])
Примечание. Методы pop (), clear (), keys () и values () помогают управлять
содержимым словаря, позволяя удалять элементы, очищать словарь и полу-
чать ключи и значения.
Метод items () возвращает объект типа diot i terns, который содержит па-
ры «ключ-значение» из словаря.
Синтаксис:
items = my_dict. items()
Предположим, у нас есть словарь, который хранит информацию о странах
и их населении:
country-population = {
"Россия": 145912025,
"США": 331002651,
"Китай": 1439323776
items = country_population.items()
print(items) # Выводит: dict_items([('Россия', 145912025), ('США',
331002651), ('Китай', 1439323776)])
Чтобы изменить значение, связанное с определенным ключом, достаточно
присвоить ему новое.
Синтаксис:
my_dict[Kn»4] = новое_значение
Чтобы обновить население США в словаре, можно сделать следующее:
country_population["CUIA"] = 332915073 # Обновляем значение для "США"
print(country_population) 4 Выводит: ('Россия': 145912925, 'США':
332915073, 'Китай': 1439323776}
Примечание. Метод items() позволяет получить все пары «ключ-значе-
ние» в словаре, а изменить значение можно, присвоив новое уже существую-
щему ключу.
Словари как инструмент для хранения данных
Словари предоставляют мощные возможности для хранения и организации
данных. Их уникальные ключи позволяют быстро получать доступ к значе-
ниям, а множество встроенных методов упрощают работу с ними.
Проверка наличия ключа в словаре
Для проверки наличия ключа используется оператор in. Так мы избежим
ошибок при попытке доступа к отсутствующим ключам.
Пример
Допустим, у нас есть словарь, который хранит информацию о животных
и их количестве:
animal count = {"ссбаки": 5, "кошки": 3, "попугаи": 7}
# Проверяем, существует ли ключ "кошки"
if "кошки" in animal_count:
print("Ключ 'кошки' существует в словаре.")
else:
print("Ключ 'кошки' не найден.")
Код выведет «Ключ < кошки > существует в словаре.», так как этот ключ при-
сутствует в animal_count.
country_populatlon("CWT] - 332915073 * Обновляем значение для "СЯА"
prlnt(country_populatlon) » Выводит: {Россия': 145912025, СИА’: 332915073, 'Китай’: 1439323770}
{’Россия’: 145912025, ’США’: 332915073, ’Китай’: 1439323776}
Q aniealcount • {“собаки”: 5, "ковки": з, "попугаи”: 7}
• Проверяем, существует ли ключ "кшнси"
If “ковки" ir anieal_count;
print("Ключ кошки* существует в словаре.")
else:
print("Ключ кошки* не найдем.")
— клоч ’кошки' существует в словаре.
book-inventory • {"Война и мир": 3, "451 градус по Фаренгейту”: 5, "Тихий Дон": 2}
for key in book_inventory;
print(key)
война и ммр
451 градус по Фаренгейту
Тихий Дон
for key in book-inventory:
value - book_inventory[key] • Доступ к значению no ключу
print(f”Kmo4: '{key}’. Значение: {value}")
Ключ: 'Война и мир*. Значение: 3
Ключ: ’451 градус по Фаренгейту', Значение: 5
Ключ: ’Тихий Дон', Значение: 2
for key in txx>k_inventory:
Рис. 5.9
Таким образом, словари — это удобный инструмент для храпения данных,
который обеспечивает простоту доступа и проверки наличия ключей.
Проход по словарю в цикле
Словари можно итерировать в цикле для выполнения различных операций,
и чаще всего для этого используется цикл for.
Итерация по ключам
При итерации по словарю по умолчанию перебираются ключи.
Пример 1. Вывести на экран каждый ключ
Допустим, у нас есть словарь, который хранит информацию о разных ви-
дах книг и их количестве на складе:
book_inventory = ("Война и мир": 3, "451 градус по Фаренгейту": 5, "Ти-
хий Дон": 2}
for key in book_inventory:
print(key)
Этот код выведет:
Вейна и мир
451 градус по Фаренгейту
Тихий Дон
Пример 2. Использование ключей для получения связанных значений
for key in bock_inventory:
value = book_ir.ventory[key] # Доступ к значению по ключу
print(f"Ключ: '{key}', Значение: {value}")
Результат:
Ключ: 'Война и мир', Значение: 3
Ключ: '451 градус по Фаренгейту', Значение: 5
Ключ: 'Тихий Дон', Значение: 2
Пример 3. Выполнение каких-либо действий с ключами
for key in book_inventory:
print (Г’Ключ: '{key}', Длина ключа: {ien(key)}") # Выводим длину
каждого ключа
Этот код выведет:
Ключ: 'Война и мир', Длина ключа: 13
Ключ: '451 градус по Фаренгейту', Длина ключа: 25
Ключ: 'Тихий Дон', Длина ключа: 9
for key in book-inventory;
value - booklnvcntoryfkey) « Доступ к 1мзчеиию по ключу
print (fK/шоч: ‘{key}*. Значение: {value}-)
Ключ: ’Война и мир’. Знамен»*»: 3
Ключ: '451 градус по Оаренгейту', Значение: 5
Ключ: 'Тихий Дон', Значение: 2
Q for key in book_inventory:
print (f-Ключ: '(key}’. Длина клоча: {l»n(key)}") • Выводим длину каждого клоча
••• Ключ; 'Война и мир’. Длина ключа: 11
Ключ: '451 градус по Оаренгейту’, Длина ключа: 24
Ключ: 'Тихий Дон', Длина клоча: 9
plant_heights - {"Роза": 30, "Кактус": 10, "Подсолнух": 150}
for key, value in plant_heights.itees():
if value > 26:
print(f”{key} имеет высоту больше 20 см.")
Роза имеет высоту больше 20 см.
Подсолнух имеет высоту больше 20 см.
а Исходашй словарь с весами камней
stone.weights - {"Гранит": 2500, "Мрамор": 2700, "Базальт": 3000, “Сланец": 1800}
w Создаем новый словарь для хранения камней с весом меньше 3000
updated_stones - {}
for key, value in stone_welghts.itees():
if value < 3000: • Условие для фильтрации
updated_stones[key] • value
Рис. 5.10
Итерация по словарю позволяет легко получать доступ к ключам и значе-
ниям, а также выполнят ь различные операции с элементами словаря.
Можно использовать условные операторы в цикле для выполнения опре-
деленных действий в зависимости от значений.
Синтаксис:
for key, value in my diet.items():
if условие:
If действия, если условие истинно
Пример
Предположим, у нас есть словарь с названиями растений и их высотой
в сантиметрах:
plant_heights = {"Роза": 30, "Кактус": 10, "Подсолнух": 150}
for key, value in piant_neights.items():
if value > 20:
print(f"{key} имеет высоту больше 20 см.")
Этот код выведет все ключи (названия растений), высота которых больше
20 см:
Роза имеет высоту больше 20 см.
Подсолнух имеет высоту больше 20 см.
С помощью циклов и условных операторов вы можете гибко обрабаты-
вать данные в словарях, проверять условия и выполнять действия с ключами
и значениями.
Изменение словаря во время итерации
Изменять словарь во время его итерации рискованно, так как это может при-
вести к ошибкам или непредсказуемому поведению. Например, удаление или
добавление элементов может привести к пропуску некоторых элементов или
возникновению ошибок.
Как правильно изменять словарь во время итерации:
1. Создание нового словаря. Один из безопасных способов — это создать
новый словарь и добавлять в него элементы в процессе итерации.
Пример
Допустим, у нас есть словарь, который хранит информацию о различных
камнях и их весе в граммах:
# Исходный словарь с весами камней
stor.e_weights = ("Гранит": 2500, "Мрамор": 2700, "Базальт": 3000, "Сла-
нец": 1800}
# Создаем новый словарь для хранения камней с весом меньше 3000
updated_stor.es = {}
for key, value in stone_weights.items():
if value < 3000: * Условие для фильтрации
updated_stcr.es [key] = value
f Перезаписываем старый словарь
stone_weights = updated_stones
# Выводим обновленный словарь
printfstone weights) # Ожидаемый вывод: {'Гранит': 2500, 'Мрамор':
2700, 'Сланец': 1800}
Подсолку а к«еет высоту бол^е 20 см.
ф • Исходный словарь с весами камней
stoneweights - {"Гранит”: 2500, "Мрамор": 2700, "Базальт”: 3000, "Сланец”: 1800}
« Создаем новый словарь для хранения камней с весом меньше 3000
updated.stones - {}
for key, value in stone_weights.lte«():
if value < 3000: » Условие для фильтрации
updatedstones[key] • value
• Перезаписываем старый словарь
stone_weights • updated_stor»es
9 Выводим обновленный словарь
print($tcne_weights) • Оюшае*ый вывод: {‘Гранит’: 2500, ’Мрамор’: 2700, ’Сланец’: 1800}
••• {’Гранит': 2500, ‘Мрамор’: 2700, ’Сланец': 1800}
rested diet - {
"жмаотчйе": {
"собака": 3,
"кошка”: 7,
}.
"птицы”: {
“попугай": 2,
"©оробей": 10,
}
• Доступ к элементам вложенного словаря
print(nested_dlct[”KMBOTwe"]("собака"]) в Выводит: 3
9 Итерация по вложенному словарю
for category, iteas in nested_dict.ite«s():
print(f"^category :")
Рис. 5.11
В этом примере создается новый словарь updated_stones, куда будут до-
бавлены только те камни, вес которых меньше 3000 граммов. После заверше-
ния итерации старый словарь stone_weights заменяется новым.
Примечание. Изменение словаря во время его итерации требует осторож-
ности. Создание нового словаря во время итерации — это один из безопас-
ных способов избежать ошибок или пропусков элементов.
Вложенные словари в Python
Словари в Python могут содержать другие словари в качестве значений, что
позволяет создавать более сложные иерархические структуры данных, отра-
жающие взаимоотношения между различными наборами информации.
Пример:
nesned_dict = {
"животные": {
"собака": 3,
"кошка": 7,
),
"птицы": {
"попугай": 2,
"воробей": 10,
)
s Доступ к элементам вложенного словаря
Python
print(nested_dict["животные"]["собака"]) 4 Выводит: 3
# Итерация по вложенному словарю
for category, items in nested diet.items():
print(f"{category}:")
for item, quantity in items.items():
print (f" {item}: {quantity}")
Этот код выводит:
животные:
собака: 3
кошка: 7
птицы:
попугай: 2
воробей: 10
Словари — это мощный инструмент для хранения структурированных
данных. Итерация по ключам и значениям позволяет гибко работать с дан-
ными, а условная обработка — применять логику к каждому элементу.
Метод get () позволяет извлекать значение по ключу с возможностью ука-
зания значения по умолчанию, если указанный ключ отсутствует. Это обес-
печивает более безопасный доступ к элементам и предотвращает возникно-
вение ошибки KeyError.
# Создаем словарь с некоторыми предметами и их ценами
my diet = {
"ноутбук": 8С0,
"смартфон": 600,
"планшет": ЗС9
f Используем метод get() для получения значения по ключу, который не
существует в словаре
value = my diet.get("умные часы", 0) # Вернет 0, если ключ "умные часы"
отсутствует
print(value) I Выводит: 0
ne$ted_dict • {
"животные": {
"собака": 3,
"кошка"; 7»
}.
"птицы": {
"попугай": 2,
"воробей": 10,
}
>
» Доступ к элементам вложенного словаря
print(п<*1е<1_а1сг["животмые"]("собака"J) а Выводит; з
* Итерация по вложенному словаре
for category, itees in ne$ted_dict,itees():
print(f“{categoryj:")
for item, quantity in ite*s. iteasQ:
print(f" (itee}: {quantity}")
3
хиеотше:
собака: 3
ковка: 7
птицы:
попугай: 2
воробей: 10
Q 9 Создаем словарь с некоторыми предметами и их ценами
«yjllct - £
“ноутбук": 800,
"смартфон": 600,|
"планшет": 300
%
а используем метод get() для получения значения по ключу, который не существует в словаре
value • ey_dict.get("yM«4e часы", 0) • вернет 0, если клоч “умные часы" отсутствует
print(value) w Выводит: в
Рис. 5.12
Метод update () позволяет добавлять или обновлять элементы из одного
словаря в другом. Если ключи совпадают, значения в исходном словаре будут
заменены значениями из обновляемого.
# Создаем словарь с некоторыми предметами и их ценами
my_dict = {
"ноутбук": 800,
"смартфон": 630,
"планшет": 300
# Создаем новый словарь с обновлениями цен
new_prices = {
"смартфон": 650, # Обновляем цену на смартфон
"флешка": 150 # Добавляем нсвую категорию - флешка
# Применяем метод update!) для обновления и добавления цен
my diet.update(new_prices)
ff Выводим обновленный словарь
print(my_dict)
# Выводит: {'ноутбук': 800, 'смартфон': 650, 'планшет': 300, 'флешка':
150}
Метод сору () [78] создает поверхностную копию словаря. Это полезно, ес-
ли вы хотите создать новый словарь, не изменяя оригинальный.
# Создаем словарь с некоторыми предметами и их ценами
my diet = {
"ноутбук": 800,
"смартфон": 600,
"планшет": 300
# Создаем поверхностную копию словаря с помощью метода сору О
copy_dict = my_dict.ccpy()
# Выводим оригинальный и копированный словари
print("Оригинальный словарь:", my diet)
# Выводит: Оригинальный словарь: ('ноутбук': 800, 'смартфон': 60С,
'планшет': 300}
print("Копия словаря:", copy_dict)
# Выводит: Копия словаря: {'ноутбук': 800, 'смартфон': 600, 'планшет':
300}
# Для наглядности изменим значение в оригинальном словаре
my diet["ноутбук"] = 850
# Проверим, как это отразилось на копии
print("Обновленный оригинальный словарь:", my diet)
# Выводит: Обновленный оригинальный словарь: {'ноутбук': 850, 'смарт-
фон': 60С, 'планшет': 300}
print("Копия словаря после изменения оригинала:", copy_dict)
f Выводит: Копия словаря после изменения оригинала: {'ноутбук': 8ЭС,
'смартфон': €30, 'планшет': 300}
Функция diet.tromkeys () [79] позволяет создать новый словарь с задан-
ными ключами и общим значением для всех ключей.
Давайте применим функцию diet, fromkeys () к существующему словарю.
С помощью нее можно создать новый словарь с указанными ключами и зна-
чением по умолчанию.
* прииемяем метод update() для обновления я добавления «ди
у .diet.updaterпеы_рг1см)
Выяодим обноялснмм словарь
print(ey.dict)
t выводит: {'ноутбук': W9, смартфон': 656, 'планшет': Мв, 'флешка': 150}
{'ноутбук': 800, 'смартфон': 650, 'планшет': 300, 'флешка': 150}
Q • создаем словарь с некоторьмм предметами и их ценами
y.dict • {
"ноутбук": 800,
"смартфон": we,
"планшет": loci
•>
в Создаем поверхности/» колка словаря с ломсчыо метода с о РУ О
copy.dlct "yjHct.copyO
* выводим оригинальный и копированный словари
print("Оригинальный словарь:", ey_dict)
• Выводит- Оригимаяъм^к словарь: {'ноутбук': 800, 'смартфон': 60в, планшет’: 300}
print("Копия словаря:", copyjlict)
выводит: Копия словаря: {’ноутбук': вйв, 'смартфон': 600, 'плашет•: «>)
а Для наглядности наменян значение я оригинальном словаре
y_dict("ноутбук"} • 880
» проверим, как это отразилось на ко<*и
print("Обновленный оригинальный словарь:", ey.dict)
а Выводит: Обновленный оригимальтшй словарь: {'ноутбук': 850, 'смартфон': 600. 'планшет': ЭМ}
printCKomu словаря после намемеммл оригинала:", copy_dict)
• Выводит копия словаря после изменения оригинала: {'ноутбук': 800, 'смартфон': 6«, 'планшет' ЭМ}
Орягмналь»шй словарь: {'ноутбук' 8W, 'смартфон': 606, 'плаютт': 300)
копил словаря: {'ноутбук' 800, 'смартфон : 600, 'планшет': Зев}
Обновленный ори г имальмш словарь: ('ноутбук': 850, 'смартфон': 600, 'планшет'; 300}
Копил словаря после иэчемемял оригинала: {'ноутбук'; В00, 'смартфон': 600, 'планшет': 300}
Рис. 5.13
Мы будем использовать названия предметов из оригинального слова-
ря в качестве ключей, а значением по умолчанию будет, например, «недо-
ступно».
# Создаем словарь с некоторыми предметами и их ценами
my_dict = {
"ноутбук": 80С,
"смартфон": 600,
"планшет": 300
}
# Создаем новый словарь с использованием dict.fromkeys(),
# где ключами будут названия предметов, а значением по умолчанию - "не-
доступно"
new_oict = dict.fromkeys(my diet.keys(), "недоступно")
# Выводим новый словарь
print(new diet)
# Выводит: {'ноутбук': 'недоступно', 'смартфон': 'недоступно', 'план-
шет' : 'недоступно'}
Мы создали новый словарь new_dict, используя ключи из оригинального
словаря my dict. Все ключи в новом словаре имеют одно и то же значение по
умолчанию — «недоступно». Таким образом, методом fromkeys () мы создали
новый словарь на основе ключей другого словаря.
Использование def aultdict из модуля collections
Если требуется работать со словарями, где значения по умолчанию могут
автоматически устанавливаться для отсутствующих ключей, можно исполь-
зовать defaultdict из модуля collections.
from collections import defaultdict
default_dict = defaultdict(float) # Значения по умолчанию - O.C
default_dict["тетрадь"] +=2.5
print(default_dict) if Выводит: defaultdict(<class 'float'>, {'тетрадь':
2.5})
Итерация с помощью генераторов
Словари используют в сочетании с генераторами для более компактного
и функционального написания кода.
cubed^dict = {х: х**3 for х in range(5)} # Генераторное выражение для
создания словаря
print(cubed_diet) # Выводит: {0: 0, 1: 1, 2: 8, 3: 27, 4: 64}
Непорядковые словари (3.7+)
Начиная с версии 3.7 словари сохраняют порядок добавления пар «ключ-
значение». То есть элементы могут быть перебраны в том порядке, в котором
были добавлены, что иногда важно.
Кортежи
Кортеж в Python [80} — это структура данных, представляющая собой неиз-
меняемую последовательность элементов. Кортежи — один из встроенных
типов данных; они позволяют группировать связанные значения, которые не
должны изменяться во время работы программы. 11одобно спискам, кортежи
могут содержать элементы различных типов, включая числа, строки, списки
и даже другие кортежи.
Характеристики кортежей
Кортежи неизменяемы, значит, созданные элементы нельзя изменять, до-
бавлять или удалять. Это обеспечивает возможность безопасного использо-
вания кортежей в качестве ключей в словарях и позволяет использовать их
в многопоточных средах без риска изменения данных.
Элементы в кортежах имеют фиксированный порядок, и доступ к ним
осуществляется по индексам — начиная с нуля.
Упорядоченность позволяет удобно обращаться к отдельным элементам
кортежа, зная их позиции.
Кортежи создаются путем заключения элементов в круглые скобки (),
а между ними ставятся запятые.
Пример
my_tuple = (1, 2, 3, "Python")
Элементы кортежа доступны но индексам, как в списках. Например, что-
бы подучить первый элемент кортежа, можно использовать такой код:
first_element = my_tuple[0]
first element fr Вернет 1
С кортежами можно выполнять различные операции, включая объедине-
ние с помощью знака +, дублирование элементов знаком *, а также проверку
наличия определенных элементов с помощью in и not in. Например:
# Создаем кортеж с некоторыми числами
my_tuple = (1, 2, 3)
I Объединение кортежей
new_tuple = my_tuple + (4, 5) » Объединяем my_tuple с новым кортежем
(4, 5)
print("Объединенный кортеж:", new tuple)
f Выводит: Объединенный кортеж: (1, 2, 3, 4, 5)
я Дублирование кортежа
replicatedtuple = my_tuple * 2 # Дублируем mytuple
print("Дублированный кортеж:", replicated_tuple)
# Выводит: Дублированный кортеж: (1, 2, 3, 1, 2, 3)
# Проверка наличия элемента в кортеже
exists = 2 in my_tuple * Проверяем, есть ли число 2 в my_tuple
print("Содержит ли my_tuple число 2?", exists)
# Выводит: Содержит ли my_tuple число 2? True
а Проверка наличия элемента, которого нет
exists = 4 in my_tuple # Проверяем, есть ли число 4 в my tuple
print("Содержит ли my_tuple число 4?", exists)
# Выводит: Содержит ли my tuple число 4? False
flrst.eleetnt Вернет 1
Q г Объединение <с ежей
new.tuple иу_tuple * (4, 5) в Объединяем eytuple с новый кортежем (4, 5)
рг1пС(‘0(>ь*димеышй кортеж:", new. tuple)
• быведот: ОбъедкненньЛ кортеж (1, 2, 3, 4, 5)
в Дублирование кортеже
repllcetedtuple - eytuple • 2 Дублируем wy_tuple
рг1п1("Дублир©в4ммы> кортеж: ”, replic*xed_tuple)
Выводит Дубяиро*«ишй кортеж: (1, 2, 3, 1, 2, 3)
• проверка мали>*а элемента в кортеж*
exists - 2 in ey.tuplt в проверяем, есть ли число 2 в eytuple
prlnt(*C4MHpraT ли ey_tuple число 2?“. exists)
выводит: Содержит ли ay_tuple число 2? True
• Проверка наличии элемента, которого нет
exists - 4 in ву_tuple • Проверяем, есть ли число 4 в eytuple
print(Чдверотт ли eytuple число 4?", exists)
* Выводит; содержит ли еу_tuple число 4? Feist
I
— объединен»** кортеж: (1, 2, Э, 4, 5)
Дублированный корте* (1, 2, 3, 1, 2, 3}
Содержит ли eytuple число 2? True
Содержит ли eytuple число 4> False
мапииите програюмД код или сгенерируйте его с помоем искусственного интеллекта.
Сотлеем <!Ива1иый кортеж с ре>пич»вв*и типами данных
alxed_tuple - (1.14, ‘Hello", True, (1, 2, 3))
Рис. 5.14
Кортежи удобны для храпения связанных данных при гарантии, что они
не изменяются. Это позволяет сохранять целостность информации и избе-
гать случайных изменений.
Создание кортежа из одного элемента
Для создания кортежа, содержащего только один элемент, необходимо доба-
вить запятую после элемента, иначе Python не распознает его как корт еж.
Пример:
single_element_tuple = (42,) I Это кортеж с одним элементом
Без запятой код будет восприниматься как выражение.
Содержимое кортежа
Кортеж может содержать данные различных типов, что позволяет исполь-
зовать их для группировки различных значений.
Пример:
mixed_tuple = (3.14, "Helle", True, [1, 2, 3])
Кроме того, кортеж можно создать с помощью встроенного конструктора
tuple (), который позволяет преобразовывать другие последовательные типы
данных, такие как списки и строки, в кортежи:
list to.tuple = tuple([l, 2, 3])
strina_to tuple = tuple("Python")
f Бернет кортеж с отдельными символами
Доступ к элементам кортежа
Доступ к элементам кортежа осуществляется так же, как и в списках, — с по-
мощью индексации. Помните, что индексация начинается с нуля:
print(mixed_tuple[0]) # Выводит: 3.14
print (mixed tuple[Ij) fr Выводит: Hello
Индексы могут быть как положительными, так и отрицательными. Отри-
цательные индексы считаются с конца кортежа:
print(mixed_tuple(-1]) # Выводит: [1, 2, 3] (последний элемент)
Пример:
# Создаем смешанный кортеж с различными типами данных
mixed_tuple = (3.14, "Hello", True, [1, 2, 3])
< Конструктор tuple()
list_to tuple = tuple([1, 2, 3]) if Преобразуем список в кортеж
string_to_tuple = tuple("Python") # Преобразуем строку в кортеж символов
t Выводим созданные кортежи
print("Кортеж из списка:", list_to_tuple) и Выводит: Кортеж из списка:
(1, 2, 3)
print("Кортеж из строки:", string to_tuple) # Выводит: Кортеж из стро-
ки: ('?', 'у', ’t', 'h', 'o', 'n')
я Доступ к элементам кортежа
print("Первый элемент mixed_tuple:", mixed tuple(Ol) # Выводит: 3.14
print("Второй элемент mixed_tuple:", mixed_tuple(U) # Выводит: Helle
v Доступ к последнему элементу с помощью отрицательного индекса
print("Последний элемент mixed_tuple:", mixed_tuple[-l]) # Выводит: [1,
2, 3]
I# Объединение кортежей
new tuple = mixed tuple + (4, 5) # Объединяем mixed_tuple с новым кор-
тежем (4, 5)
print("Объединенный кортеж:", new tuple) # Выводит: Объединенный кор-
теж: (3.14, 'Hello', True, [1, 2, 31, 4, 5)
# Дублирование кортежа
replicated_tuple = mixed_tuple * 2 fl Дублируем mixed_tuple
print("Дублированный кортеж:", replicaoed_tuple) fl Выводит: Дублиро-
ванный кортеж: (3.14, 'Hello', True, [1, 2, 3], 3.14, 'Hello', True, [1,
2, 3])
# Проверка наличия элемента в кортеже
exists_true = True in mixed_tuple f Проверяем, есть ли значение True
в mixed_tuple
print("Содержит ли mixed tuple значение True?", exists true) # Выводит:
True
exists_hello = "Hello" in mixed_tuple # Проверяем, есть ли строка
"Hello" в mixed tuple
print("Содержит ли mixed_tuple строку 'Hello'?", exists_hello) # Выво-
дит: True
exists_4 = 4 in mixed_tuple # Проверяем, есть ли число 4 в mixed_tuple
print("Содержит ли mixed_tuple число 4?", exists 4) fl Выводит: False
Описание:
1. Создаем смешанный кортеж mixed tuple, который содержит плавающее
число, строку, логическое значение и список.
2. Используем конструктор tuple () для преобразования списка и строки
в кортежи.
3. Получаем доступ к элементам с помощью положительных и отрица-
тельных индексов.
4. Объединяем и дублируем кортежи.
5. Проверяем наличие различных элементов в кортеже с использованием
оператора in.
Списки
Списки в Python — это упорядоченные изменяемые коллекции, которые мо-
гут содержать элементы различных типов. Они представляют собой одну из
основных структур данных и служат для хранения последовательных данных,
таких как числа, строки или даже другие списки. Их важная особенность —
возможность добавлять, удалять и изменять элементы.
Создание списков
Существует несколько способов создания списков. Рассмотрим некоторые
из них.
1. Квадратные скобки:
my_list = [1, 2, 3, 4, 5] 4 Создаем список с целыми числами
2. Пустой список:
empty_list = []
^Создаем пустой список, который можно наполнять позже
3. Функция list ():
another_list = list((6, 7, 8)) # Конвертируем кортеж в список
4. Генератор;
squareo_list = [х*’2 for х in range(5)]
# Создаем список квадратов чисел от 0 до 4
5. Функция range () :
range_list = list(range(10)) # Создаем список чисел от 0 до 9
Доступ к элементам списка
Элементы списка можно получить по их индексам. Индексация начинается
с нуля, поэтому первый элемент имеет индекс 0, второй — 1 и т. д. Также
можно использовать отрицательные индексы для доступа к элементам с кон-
ца списка, где -1 — последний элемент, -2 — предпоследний и г. д.
Пример:
my list = [10, 20, 30, 40, 5.']
print(my_list[0]) ff Выводит: 10
print(my_list[1]) # Выводит: 20
print(my_list[-1]) # Выводит: 50 (последний элемент)
Создадим общий пример этих методов.
Описание:
1. Покажем различные способы создания списков: с помощью квадратных
скобок, пустого списка, функций list ()и range () и генераторов.
2. Продемонстрируем доступ к элементам списка по индексам, включая
использование отрицательных.
3. Покажем, как изменить элемент списка, добавить новый и удалить эле-
мент и сортировать список.
4. Отобразим пример объединения двух списков.
5. Напечатаем все элементы объединенного списка с их индексами.
Пример:
# 1. Создание списка с псмсщью квадратных скобок
my_list = (1, 2, 3, 4, 5] * Создаем список с целыми числами
print("Список с псмсщью квадратных скобок:", my_list)
♦ 2. Создание пустого списка
empty list = [] I Создаем пустей список
print("Пустой список:", empty_list)
If 3. Создание списка с использованием функции list О
another_list = list((6, 7, 8)) 4 Конвертируем кортеж в список
print("Список из кортежа:", ancther_list)
# 4. Создание списка с использованием генератора
squared_list = [х**2 for х in range(5)] i Создаем список квадратов чи-
сел от 0 до 4
print("Список квадратов чисел от 0 до 4:н, squared_list)
# 5. Создание списка с использованием функции range ()
range_list = list(range (10)) # Создаем список чисел от 0 до 9
pr:nt("Список чисел от С до 9 с использованием range():", range list)
J Доступ к элементам списка
print("\пДоступ к элементам списка:")
access list = (10, 20, 30, 40, 50]
print ("Первый элемент:", access_list[0]) if Выводит: 10
print("Второй элемент:", access list[l]) # Выводит: 2С
print("Последний элемент:", access_list[-1]) I Выводит: 50 (последний
элемент)
# Изменение элементов списка
access list[lj = 25 # Изменяем втсрсй элемент на 25
print("Измененный список:", access_list) # Выводит: [10, 25, 30, 40, 50]
# Добавление элементов в список
empty list.append(ICO) # Добавляем элемент в пустой список
print("Пустой список после добавления элемента:", empty_list)
# Удаление элемента из списка
access_list.remove(30) I Удаляем элемент 39 из списка
print("Список после удаления элемента 30:", access_list)
ff Сортировка списка
unsorted_list = [5, 3, 8, 1, 2]
unsorted_list.sort() # Сортируем список
print("Отсортированный список:", unsorted_list)
# Объединение списков
ccmbined_list = my_list + another_list # Объединяем два списка
print("Объединенный список:", combinedjlist)
# Итоговые операции с элементасли
print("\пИтоговые операции:")
for i in range(len(combined list)):
print(f'Элемент с индексом (i): [combined_list[i]}")
ylist [1, 2, 3, 4, 5] 9 Создаем список с целыми числами
print("Список с помошью квадратных скобокay_list)
• 2. Создание пустого списка
e«pty_list • (] • Создаем пустой список
рг1т("Пустой список:", e«pty_list)
* 3. Создание списка с использованием функции Hst()
another_list - Iist((6, 7, Я}) в Конвертируем кортеж в список
print("Список из кортежа:’, another_list)
9 4. Создание списка с использованием генератора
squared_list - [х**2 for к in range(S)] • Создаем список квадратов чисел от Я до 4
print("Слисок квадратов чисел от 0 до 4:’, s<iuared_li* *t)
# 5. Создание списка с использованием функции range()
range.list - list(range(ie>) в Создаем список чисел от 0 до 9
print(“Список чисел от 0 до 9 с использованием range():", range_list)
9 Доступ к элементам списка
print("\nflocryn к элементам списка:’)
access.Hst - (10, 2в, ЗФ, 4ф, 50]
print("Первый элемент:", acce$s_list(0]) • Выводит: 10
рг!пГ("Второй элемент:", access_list[l]) в Выводит: 20
print("Последний элемент:’, access_list[-i)) 9 Выводит: 50 (последний элемент)
9 Изменение элементов списка
access_list[1] - 25 # Изменяем второй элемент на 25
рг1пТ("Иэмененмый список:’, access_list) В Выводит: [10, 25, 30, 40, 50]
9 Добавление элементов в список
e«ptу-llst.append(100) в Добавляем элемент в пустой список
print(“Пустой список после добавления элемента:", eepty_list)
9 Удаление элемента из списка
access-list.renove(30) 9 Удаляем элемент 3® из списка
print("Список после удаления элемента 30:", access_list)
в Сортировка списка
unsorted_list [5, 3, 8, 1, 2]
unsorted-list.sort() • Сортируем список
print("Отсортированный список:", unsorted_list)
9 Объединение списков
coabined_list eylist ♦ another_list в Объединяем два списка
print("Объединенный список:", coabined.llst)
• Итоговые операции с элемент аж
print(“ЧпИтоговые операции:’)
Рис. 5.15
• Объединение списке*
coeblnedllst ey_list ♦ another_llst * Объединяем два списка
print(“Объединенный список:*, co*bined_ll$t)
» Итоговые операции с элементами
рг1п1§"\пИтоговые операции
for 1 in range(len(coabined_list)):
print(f“Элемент с индексом {!}: {coebined_list[i]}“)
Список с помокыо квадратных скобок: (1, 2, 3, 4, 5]
Пустой список: []
Список м> кортежа: (6, 7, 8)
Список квадратов чисел от О до 4: [0, 1, 4, 9, 16)
Список чисел от е до 9 с использованием range(): [в, 1, 2, 3, 4, 5, 6, 7, 8, 9)
Доступ к элементам списка:
Первый элемент: 10
Второй элемент: 29
Последний элемент: 59
И>менеи1*1й список: (18, 25, 38, 48 , 58)
Пустой список после добавления элемента: [188]
Список после удаления элемента 38: (18, 25, 48, 58)
Отсортированный список [1, 2, 3, 5, 8)
Объединенный список: (1, 2, 3, 4, 5, 6, 7, 8)
Итоговые операции:
Элемент с индексом 8: 1
Элемент с индексом 1: 2
Элемент с индексом 2: 3
Элемент с индексом 3: 4
Элемент с индексом 4: 5
Элемент с индексом 5: б
Элемент с индексом 6: 7
Элемент с индексом 7: 8
ey_list - (1, 2, 3]
y_list.append(4) в Добавляем элемент 4
print(«y_U$t) • Выводит: [1, 2, 3, 4)
y_list.extend([5, 6)) « Добавляем элементы 5 и б
Рис. 5.16
Основные операции со списками
Добавление элементов
Для добавления одного элемента в список можно использовать метод
append (), а для нескольких — extend ():
my list = [1, 2, 3]
my_list.append(4) # Добавляем элемент 4
print(my_list) # Выводит: [1, 2, 3, 4]
my list.extend)[5, 6]) fl Добавляем элементы 5 и 6
print(my_list) fl Выводит: [1, 2, 3, 4, 5, 6]
Удаление элементов
Для удаления элемента по значению можно использовать метод remove (),
а по индексу — pop ().
my_list = [1, 2, 3, 4, 5]
my_list.remove(3) fl Удаляем элемент co значением 3
print(my_list) # Выводит: [1, 2, 4, 5]
removed_element = my_list.pop(l) # Удаляем элемент по индексу 1
print(removed_element) fl Выводит: 2
print(my_list) # Выводит: [1, 4, 5J
Объединение
Списки можно объединять с помощью оператора + или метода extend ().
list_a = [1, 2, 3]
list_b = [4, 5]
combir.ed_l.ist = list_a + list_o # Объединение с помощью оператора +
print(ccmbined_list) * Выводит: [1, 2, 3, 4, 5]
list_a.extend(list_b) # Объединение с помощью метода extendi)
print(lista) # Выводит: [1, 2, 3, 4, 5]
Копирование
Копировать список можно с помощью среза или метода сору ().
cnginal_list = [1, 2, 3]
copied list = original list[:] ff Копирование с помощью среза
print(copied_list) if Выводит: [1, 2, 3]
copied list2 = original list.copy!) # Копирование с помощью метода
серу ()
print(copied_list2) # Выводит: [1, 2, 3]
Сортировка
Списки можно сортировать с помощью метода sort() или функции
sorted().
my list = (5, 2, 1, 4, 3]
ту list.sort() # Сортируем в порядке возрастания
print(my_list) # Выводит: [1, 2, 3, 4, 5]
f Сортировка с использованием функции sorted!)
sorted_list = sorted! [3, 1, 4, 1, 5, 9, 2])
print(sorted_list) # Выводит: [1, 1, 2, 3, 4, 5, 9]
Списки обеспечивают удобный и мощный способ хранения множест-
ва элементов с возможностью их модификации. Создание, изменение и уп-
равление ими — ключевые навыки в изучении Python и программировании
в целом.
Приведем примеры трех уровней сложности работы со списками: прос-
той, средний и продвинутый. Каждый сопровожден поясняющими коммен-
тариями.
Простой уровень
Пример 1. Создание, добавление и доступ к элементам
ft Создаем пустой список
my_list = []
# Добавляем элементы в список с помощью метода append!)
my_list.append(10) ft Добавляем 10 в список
my_list.append(20) ft Добавляем 20 в список
my_list.append(30) ft Добавляем 30 в список
# Доступ к элементам списка по индексам
print(my_list[0)) # Выводит: 10 (первый элемент)
print(my list[l]) # Выводит: 20 (второй элемент)
print(my_list[2]) # Выводит: 30 (третий элемент)
Средний уровень
Пример 2. Объединение, сортировка и удаление элементов
ft Создаем два списка
list_a = [5, 1, 3]
list_b = [4, 2]
# Объединяем списки с помощью оператора +
combined_list = list_a + list_b ft Объединяем list а и list_b
print(combined list) ft Выводит: [5, 1, 3, 4, 2]
ft Сортируем объединенный список
corr.bined_list.sort() ft Сортируем элементы в порядке возрастания
print(ccmbined_list) ft Выводит: fl, 2, 3, 4, 5]
# Удаляем элемент со значением 3
coirbined_list.remove (3) ft Удаляем 3 из списка
print(combined list) * Выводит: [1, 2, 4, 5]
© • Соэдмм ДМ СГМСК4
Нм . - [S, u Ji
li«_b - (4. 21
• 0бъвд****я* *и списки с помс^й оператор* ♦
coeOined_llst ♦ Ustjb » О&ьедияяеи list.» и list.b
print (coet>lr»ed_ list) выводи! (5, 1, J, 4, 2]
• Сортируем оЬъедииемнмЙ список
coat>ln«d_Ilst.M<,t() • Сортируем елеменп* « порядке лоэрястлмия
print(coetolned_Ilst) » выводит: [1, 2, з, 4, 5]
• Удаляем элемент со аначением 3
co^>in*d_llst.r«aQ¥«(i) * Удаляем з м> списка
print(co*fcined_l1st) выводит: (1, 2, 4, 5]
- (S. 1» 1. 4, 2]
[1, 2. >, *. S]
(Ъ 2, 4. 5]
• Начальный список чисел
nwiters - (1«, 15, 20, 25, 30]
• используем списковое вкме^енме для создания нового списка квадрате* чисел
squered.nuebers * [к •• 2 for ж In nuabers] • Кмдий алвявмт numbers возводится в квадрат
print(>диаг«<1_пидЬегв) • вводит: [106, 225, 4В0, 625, 900]
• Вумкцкя ди фильтрации четных квадратов
def filter_rven_ squires (squer»_lfst):
return (nue for пив In square_litt if пив X 2 — в] в Возарачмм только четные числа
• Применяем фуикцмо к списку квадратов
cven_s<ftu«res - f ilt«r_even_squ*resj,*qu4red_nuebers)
print (evtri_>quar*s) в Выводит: [JOO, 400, 906]
в копируем исходный список и добавляем к ****? новые элементы
copled_llst - пивЬвгв.соруО » Создаем копи* списка nuabers
copied,11 st.extend(even_sau*r«i) • добавляем четкие квадраты в копив
print(copiedJ1st) • Вьимг* [It, 15, 20» 25, JO, 100, 400, 900]
(iee, 224, аее, 625, еее]
(100, 400, оее]
[Ю, 15» 20, 25, 30» 100» 400, 900]
Рис. 5.17
Продвинутый уровень
Пример 3. Сложный процесс работы со списками с использованием списко-
вых включений и функций
? Начальный список чисел
numbers = [10, 15, 20, 25, 30]
# Используем списковое включение для создания нового списка квадратов
чисел
squared numoers = [х ** 2 for х in numbers] * Каждый элемент numbers
возводится в квадрат
print(squared_numbers) # Выводит: [100, 225, 400, 625, 900]
ft Функция для фильтрации четных квадратов
def filter_even_squares(square_iist):
return [num for num in square_list if num % 2 == С] # Возвращаем
только четные числа
# Применяем функцию к списку квадратов
even_squares = filter even squares (squared_r.umbers)
print(even squares) ft Выводит: [100, 400, 900]
# Копируем исходный список и добавляем к нему новые элементы
copied list = numbers.copy() # Создаем копию списка numbers
copied_list.extend(even_squares) ft Добавляем четкие квадраты в копию
print(copied_list) # Выводит: [10, 15, 20, 25, 30, 100, 400, 900]
Объяснение:
• Простой уровень. Этот пример показывает, как создать список, до-
бавлять в него элементы и получать к ним доступ. Используем метод
append () для добавления элементов и индексы для доступа к ним.
• Средний уровень. Объединяем два списка, сортируем результирующий
список и удаляем определенный элемент. Используем метод sort () для
сортировки и remove () для удаления элемента по значению.
• Продвинутый уровень. Работаем с более сложными концепциями —
генераторами списков, функциями и фильтрацией. Создаем новый
список, содержащий квадраты чисел, и определяем функцию для
фильтрации четных квадратов из него. Копируем исходный список
и объединяем его с новым.
Эти примеры показывают, как можно использовать списки для решения
задач с разной степенью сложности.
Функция len () в списках
Функция len () — это встроенная функция в Python, которая возвращает ко-
личество элементов в объекте. Она может быть использована для различных
типов данных, включая списки, строки, кортежи и другие коллекции. В кон-
тексте списков функция len () позволяет узнать, сколько элементов содер-
жится в списке, что может быть полезно в различных сценариях, таких как
проверка пустоты списка, выполнение циклов и реализации условий.
Пример 1 Определение длины списка
# Создаем список с шестью элементами
my list = [1, 2, 3, 4, 5, 6]
# Используем функцию len() для определения количества элементов в списке
length_of_list = len(my list) I length of list будет равен б
print(length of list) # Выводит: 6
Создаем список с шестью элементами и используем функции) len (), чтобы
получить количество этих элементов. Результат равен 6, что соответствует
количеству элементов в списке.
Пример 2. Проверка пустоты списка
# Создаем пустой список
empty_list = (1
# Используем функцию 1еп() для проверки, пуст ли список
if len(empty_list) == 0:
print("Список пуст.") # Сообщение будет выведено, так как спи-
сок пуст
else:
print("Список не пуст.")
Q । Создосм пустой слмсо«|
Mpty.iut - (]
а исгслъгуеч функции !•«() д* *я проверки. пуст *и список
if len(Mpty_l!st) «• В:
prlnt(~CnncoK пуст.") • Сообчсмяе будет выведено, так как список пуст
реInt('Стасок не пуст.")
Список пуст.
• Создаем список с мечентам*
• [‘apple', 'banana*, 'cherry']
* Исполыхусм функций 1вп() в цикла дня обхода ясах нвиятм списка
for 1 in rangef len(ey_Hit));
peint<f_3*e**Mi (1 * t)j {ву_11М[1)}’) виеодит элементы списка с их индекса**
Элемент 1: apple
Эленент 2: Ьапал»
Элемент 3: cherry
• Создаем два списка
liat.a - (1, 2, з)
Мм_Ь • ('apple’, 'banana*)
• Сравнивая* дли^* списков
if len(liat.a) > len(ll*t_b):
prlnt("liat_a содержит больве элементов, чем 114t_b.’) в Сосбоемве будет выведено
•1$а:
pelnt(“list_b содержит болым элементов, чем list_a.“)
совершт бовме элементов, чвм list_b.
• Создаем список, содержав элемента размкк типов данных
y.BiXBd.liat - [аг, True, 3.14, "Hello, World!’, (1, 2, 3], (4, 5), {'а': 1, 'Ь': 2), Sone]
в Перебираем и выводим кгади! вммемт с его типом
for element in •y.Bixed.lBv.
Рис. 5.18
Создаем пустой список и используем функцию 1еп() для проверки его
длины. Если длина равна 0, это означает, что список пуст и выводится соот-
ветствующее сообщение.
Пример 3. Использование функции 1еп() в цикле
# Создаем список с элементами
my_list = ('apple', 'banana', 'cherry']
0 Используем функцию 1еп() в цикле для обхода всех элементов списка
for 1 in range(len(my_list)):
print(f"Элемент (i + 1}: {my_list[i]}") i Выводит элементы списка
с их индексами
» Создаем пустой список
МрТу.11« - []
в Используем функцию 1еп() для проверки, пуст ли список
if l«n(«mpty_li$t) — в:
print("CnwcoK пуст.") в Сообщение будет выведено, так как список пуст
else:
print("Список не пуст.")
Список пуст.
Q В Создаем список с элемента* *»
yjlst • apple’, ’banana*, 'cherry']]
В Используем функцию 1еп() в цикле для обхода всех элементов списка
for 1 in range(len(ey_Hst)):
print(f"Элемент {1 + 1}: {y_list[i]}’) • Выводит элементы списка с их индексами
••• Элемент 1. apple
Элемент 2: banana
Элемент 3: cherry
в Создаем два списка
list.a - (1, 2, 3]
list_b • [’apple', ’banana*)
в Сравниваем длины списков
if len(list.a) > len(list.b):
print("llst_a содержит болыве элементов, чем list_b.") • Сообщение будет выведено
else:
print("Hst.b содержит болыве элементов, чем list_a.")
list_a содержит балдею элементов, чем list_b.
* Создаем список, содержащий элементы разных типов данных
y_eixed„list - (42, True, 3.14, "Hello, world!’, [1, 2, 3], (4, 5), {‘a’: 1, 'b': 2}, None)
в Перебираем и выводим каж»вй элемент с его типом
for element in ey_eixed_list:
Рис. 5.19
Используем 1еп() для получения количества элементов в списке и за-
тем перебираем все элементы с помощью цикла for. Используем функцию
range () для генерации последовательности индексов, которые дают доступ
к каждому элементу списка.
Пример 4. Сравнение длины двух списков
♦ Создаем два списка
list а = [1, 2, 3]
list_b = ['apple', 'banana'1
# Сравниваем длины списков
if len(list_a) > len(list_b):
print("list а содержит больше элементов, чем list_b.") # Сообщение
будет выведено
else:
print("list b содержит больше элементов, чем list а.")
y_nst • i appie , oanana , cnerry j
V используем функцию len() в цикле для обхода всех элементов списка
for i in range(len(ey_li$t)):
print(f"Элемент {1 ♦ 1}: {y_Mst[i)}“) • Выводит элементы списка с их индексам
Элемент 1: apple
Элемент 2: banana
Элемент 3: cherry
0 • Создаем два списка]
listл - (1, 2, 3]
list_b ['apple* *, ‘banana*]
• Сравниваем aahw списков
if len(list_a) > len(llst.b):
print("list_a содержит болыве элементов, чем list_b.’) • Сообщение будет выведено
else:
print(“list_b содержит бояьае элементов, чем llst_a.")
••• list_a содержит больше элементов, чем list_b.
• Создаем список, содержащий элементы разных типов данных
y_Blxed_llst • [42, True, 3.14, "Hello, Worldl", [1, 2, 3], (4, S), {’a‘: 1, ‘b’: 2), Hone]
• Перебираем м выводим каждый элемент с его типом
for eleeent in my_eixed_list:
print(f"Элемент: {element}. Тип: {type(eleeentl}")
Элемент: 42, Тип:: cclass *int’>
Элемент: True, Тип: Cclass *bool*>
Элемент: 3.14, Тип: cclass 'float*>
Элемент: Hello, HorioI, Тип: Cclass ’str*>
Элемент: [1, 2, 3], Tun: cclass *list‘>
Элемент: (4, 5), Тип: cclass *tuple*>
Элемент: {'a': 1, *b‘t 2), Тил: cclass ’dict’>
Элемент: Hone, Тип: cclass 'NoneType’>
• Создаем список, содержащий элементы разных типов данных
lxed_list [
25, • Целое число
Рис. 5.20
Сравниваем длины двух списков с помощью функции len (). В зависимос-
ти от результата, выводим соответствующее сообщение о том, какой из спис-
ков содержит больше элементов.
Элементы списков могут быть любого типа данных, включая, но не огра-
ничиваясь, следующими:
* целые числа;
• числа с плавающей запятой (float);
• строки;
• логические значения (True/False);
• списки (да, списки могут содержать другие списки — эго называется
вложенными списками);
• кортежи;
• словари;
* множества;
♦ объекты пользовательских классов.
Это дает огромные возможности для организации и хранения данных
в Python. Давайте рассмотрим пример, который демонстрирует это разнооб-
разие.
Пример. Список с элементами различных типов данных
# Создаем список, содержащий элементы разных типов данных
my_mixed_list = (42, True, 3.14, "Hello, World!", (1, 2, 31, (4, 5),
{'a': 1, 'b': 2), None]
j Перебираем и выводим каждый элемент с его типом
for element in myjnixedlist:
print(f"Элемент: {element), Тип: (type(element)}")
11 ien<nst_aj > ien(iisx_O);
содержит болыве элементов, чем list_b.") 9 Сообщение будет выведено
else:
print(“list_b содержит болыве элементов, чем list_a.")
list_a содержит больые элементов, чем list_b.
Q * * * ••• Создаем список, содержащий элементы разных типов даншх
»y_eixed_list - (42, True, 3.14, "Hello, World!", [1, 2, 3], (4, 5), 1, ’Ь’: 2}, None)
< Перебираем и выводим каждым элемент с его типом
for tleeent in ey_Mixed_li$t:
print^f“Элемент: {eleeent, Тип: {type(eleeent)]“)|
Элемент: 42, Тип: «class 4nt'>
Элемент; True, Тил: «class ’bool’>
Элемент: Э.14, Тип: «class 'float'>
Элемент: Hello, World!, Тип: «class *str’>
Элемент: [1, 2, 3), Тип: «class *list’>
Элемент: (4, 5), Тип: «class ’tuple’s
Элемент: {’a’: 1, b': 2), Тип: «class diet's
Элемент: None, Тип: «class 'NoneType*>
О » Создаем список, содержащий элементы разных типов даншх
ixed_list - [
25, » Целое число
3.14, 9 число с плавамщей запятой
"Python", » Строка
True, в Логическое значение
(1, 2, 3], « Вложенный список
(4, 5), в Кортеж
{‘папе*: 'Alice', 'age': 36}, * Словарь
None в Значение Ноле
1
• перебираем и выводим каждый элемент с его типом
for eleeent in nixed, list:
print(f"Элемент: {eleeent}, Тип: {type(eleeent)}")
••• Элемент: 25, Тип: «class 'int’>
Рис. 5.21
Объяснение:
1. my mixed list. Создаем список, состоящий из различных типов данных:
целое число (42), логическое значение (True), число с плавающей запятой
(3.14), строка ("Helio, World!"), вложенный список ([1, 2, 3]), кортеж ((4,
5)), словарь ({'а': 1, 'о': 2}) и значение None.
2. С помощью цикла for перебираем каждый элемент.
3. Для каждого элемента используем функцию type (), чтобы получить его
тип, и выводим вместе с самим элементом.
Ожидаемый вывод:
Элемент: 42, Тип: <class 'int'>
Элемент: True, Тип: «class 'ЬооГ>
Элемент: 3.14, Тип: «class 'float'>
Элемент: Hello, World!, Тип: «class 'str'>
Элемент: [1, 2, 3], Тип: «class 'list'>
Элемент: (4, 5), Тип: «class 'tuple'>
Элемент: {'a': 1, 'b': 2), Тип: «class 'dict'>
Элемент: None, Тип: «class 'NoneType'>
Как видно из примера, элементы списка могут принадлежать к разным ти-
пам данных.
Списки могут содержать элементы различных типов данных одновремен-
но. Это позволяет хранить в одном списке, например, целые числа, строки,
списки, кортежи и даже объекты пользовательских классов.
Пример. Список с элементами разных типов данных
Давайте рассмотрим пример списка, который содержит различные типы
данных:
# Создаем список, содержащий элементы разных типов данных
mixed list = [
25, # Целое число
3.14, # Число с плавающей запятой
"Python", # Строка
True, # Логическое значение
[1, 2, 3], # Вложенный список
(4, 5), # Ксртеж
{'name': 'Alice', 'age': 30}, # Словарь
None ff Значение None
J
s Перебираем и выводим каждый элемент с его типом
for element in mixed_list:
print(f"Элемент: {element), Тип: {type(element)}")
• Сомии cmtcwc < *»е»*»нт4т
у_Н« • (t, 2. >. 4. f]
Жложл/ФМ фуивчМ typ«() ** onp«A«A*MUi тип* объект*
list_typ< - typ*(ajr_llst) а Олремдмм i»*n песете wy list
pr!M<U»t_W*) • •»*«**<: «1*»» '1HV>
cclass *ll»t*>
а Совдмм список с *ммнт*м« типов
iMd.llst - («2, J. 14. ‘Hello’. True)
в енребмрмм »пеме«гь списка и мои»! к«вям* маиеит < «о типе*
<ЛГ ВТ <П 11*Г!
Рис. 5.22
Объяснение:
1. Создаем список под названием mixed_l ist, в который помещаем различ-
ные элементы:
• 25 — целое число (тип int);
• 3.14 — число с плавающей запятой (тип float);
• "Python" — строка (тип str);
• True — логическое значение (тин bool);
• [1, 2, 3] —вложенный список (тип list);
• (4, 5) —кортеж (тип tuple);
• {'name': 'Alice', 'age': 30}—словарь (тип diet);
• None — значение None (тип NoneType).
2. Используя цикл for, перебираем каждый элемент.
3. Для каждого элемента выводим его значение и тип с помощью функции
type ().
Ожидаемый вывод:
Элемент: 25, Тип: Cclass 'int'>
Элемент: 3.14, Тип: Cclass 'float'>
Элемент: Python, Тип: <class 'str'>
Элемент: True, Тип: <class 'bcol'>
Элемент: [1, 2, 3], Тип: <class 'list'>
Элемент: (4, 5), Тип: Cclass 'tuple'>
Элемент: ('name': 'Alice', 'age': 39}, Тип: Cclass 'dict'>
Элемент: None, Тип: cclass 'NoneType'>
Как видно из примера, список mixed list содержит элементы разных ти-
пов данных.
Функция type () в списках
type() [81] — это встроенная функция, которая возвращает тип объекта,
переданного в качестве аргумента. В контексте списков эта функция .может
быть использована для определения типа самого списка, а также типов эле-
ментов, содержащихся в нем. Это может быть полезно для проверки содер-
жимого списка, отладки и понимания структуры ваших данных.
Пример 1. Определение типа списка
if Создаем список с элементами
my list = [1, 2, 3, 4, 5]
# Используем функцию typed для определения типа объекта
list_type = type(my list) f Определяем тип переменной my_list
print(list_type) # Выводит: Cclass 'list'>
Создаем список и используем функцию type (), чтобы определить, что тип
переменной my_list — list. Это подтверждает, что мы действительно созда-
ли список
Пример 2. Определение типов элементов списка
# Создаем список с элементами разных типов
mixed list = [42, 3.14, "Hello", True]
it Перебираем элементы списка и выводим каждый элемент с его типом
for element in mixed_list:
element_type = type(element) f Определяем тип элемента
print(f"Элемент: {element}, Тип: {element_type}")
Создаем список mixed_list, который содержит элементы различных ти-
пов. Используя цикл for, перебираем каждый элемент и применяем функцию
type () для определения типа и вывода его на экран.
Ожидаемый вывод:
Элемент: 42, Тип: <class 'int'>
Элемент: 3.14, Тип: <class 'float'>
Элемент: Helle, Тип: cclass 'str'>
Элемент: True, Тип: Cclass ’ЬооГ>
Пример 3. Проверка типов элементов и выполнения условий
# Создаем список с элементами разных типов
my_list = [1, "text", 3.14, [1, 2], {"key": "value"}, None}
# Проверяем тип каждого элемента и выполняем действия в зависимости от
типа
for element in my_list:
if суре(element) == int:
print(f"(element} - это целое число.")
elif type(element) == str:
print(f"{element} - это строка.")
elif type(element) == list:
print(f"{element} - это список.")
elif type(element) == diet:
print(f"{element} - это словарь.")
elif element is None:
print("Элемент равен None.")
else:
print(f"{element} - это элемент другого типа: {type(element)}.")
Проверяем тип каждого элемента в списке my_list и выводим соответс-
твующее сообщение в зависимости от его типа. Используем функцию type ()
для определения типа каждого элемента и выполняем разные действия для
разных типов данных.
Ожидаемый вывод:
1 - это целое число.
text - это строка.
3.14 - это элемент другого типа: <class 'float'>.
[1, 2] - это список.
{'key': 'value'} - это словарь.
Элемент равен Копе.
Конструктор list () используется для создания нового списка. Это нужно,
чтобы инициализировать список пустым значением или преобразовать дру-
гие итерируемые объекты, такие как строки, кортежи, множества или другие
списки, в список.
Основные способы использования конструктора list ():
1. Создание пустого списка.
2. Преобразование итерируемого объекта в список.
3. Создание списка из элементов с помощью генерации.
Примеры использования конструктора list ():
Пример 1. Создание пустого списка
? Инициализация пустсго списка с помощью конструктора list()
empty_list = list ()
if Проверяем длину списка и выводим его содержимое
print(len(empty_list)) # Выводит: G
print(empty_list) # Выводит: []
Создаем пустой список с помощью конструктора list (). Проверяем дли-
ну списка, которая равна 0, и выводим сам список.
Пример 2. Преобразование строки в список
I Создаем строку
my string = "Hello, World!"
# Преобразуем строку в список с помощью конструктора list()
string_as_list = list(rey_string)
# Выводим результат
print (string_as_list) # Выводит: ['H', 'е', '1', '1', 'o', ' ',
'W', 'o', 'г', '1', 'd', '!',]
Строка my string преобразуется в список, где каждый символ становится
отдельным элементом. Результат показывает, что строка успешно преобразо-
вана.
Пример 3. Преобразование кортежа в список
# Создаем кортеж
my tuple = (1, 2, 3, 4, 5)
if Преобразуем кортеж в список с помощью конструктора list()
tuple_as_list = list(my_tuple)
if Выводим результат
print(tuple_as_list) * Выводит: [1, 2, 3, 4, 5]
Берем кортеж my tuple и преобразуем его в список с помощью конструк-
тора list (). Результат показывает, что элементы кортежа стали элементами
списка.
Пример 4. Создание списка из множества
# Создаем множество
my set = {1, 2, 3, 4, 5}
# Преобразуем множество в список
set_as_list = list(my_set)
» Выводим результат
print(set_as_list) I Выводит: [1, 2, 3, 4, 5] (порядок может отличаться,
так как множество неупорядочено)
print(strin<-»s_list) • Выводит: (’и', е', ’14 '14 ’©4 ' 4 * *М4 *©4 ’г’, *1*, 'd', '14)
('«4 ’«4 '14 Г, 'o’, 44 ' 4 W4 ’о4 Г, '64 *1*1
• Создам кортеж
y^tuple - (1, 2, Ъ 4, 5)
» Преобразуем кортеж в смсок с помочь» конструктора list()
tuple„*s..lUt - lBt(ey_tuplo)
• Вывод*»* результат
print(tuple.as.l1st) » Выводит: (1, 2» 3, о, 5]
(1. 2, 3. 4. SJ
ф * Создаст* мможестно
- (1, 2, 3. 4. $}
* Преобразуем ммсисгстоо список
> et_»s_list - li»t(ey_sot)
• Вывод»»* результат
print(sBt_as_list) в Выводит: (I, 2, 3, 4, 5] (порядок может отличаться, так как множество неупорядочено)
- [1, 2. 3, 4. 5]
• Создаст* список квадратов чисел от О до 4 С помосты» генератора
squares list(x •• 2 for х in range(S))
• Выводим результат
print(squares) » Выводит: [О, 1, *, 9, 16]
[О» 1» 4» 9» 16]
• Создам список с мтсмсбмллми
cars - ("Toyota’, "Ford", "виг, ‘Honda", "Hyundai", "Mercedes", "Audi")
f Доступ к элементам по индексу
pcint("Jj0<Tyn к элементам:")
print(cars(l)) е Выводит. Ford
print(cars(-l)) v выводит: Audi
• Срезы
Рис. 5.23
Преобразуем множество my_set в список. Обратите внимание, что поря-
док элементов может отличаться от порядка во множестве, так как множест-
во в Python — это неупорядоченная коллекция.
Пример 5. Использование конструктора list () с генераторами
* Создаем список квадратов чисел от 0 до 4 с помощью генератора
squares = list(x ** 2 for х in range(5))
# Выводим результат
print(squares) f Выводит: [О, 1, 4, 9, 16]
Используем генератор для создания списка квадратов чисел от 0 до 4 и пе-
редаем его в конструктор list (). Результат — список квадратов.
Конструктор list () — это мощный инструмент для создания и преобразо-
вания данных в Python. Он позволяет легко инициализировать новые списки,
преобразовывать другие итерируемые объекты и работать с данными более
эффективно. Иногда использование конструктора list () — предпочтитель-
ный способ создания списков по сравнению с квадратными скобками ([]),
особенно когда вы работаете с итерируемыми объектами.
Индексы и срезы в списках
Доступ к элементам списка осуществляется по индексу. Это целые числа, ко-
торые указывают на позицию элемента внутри списка начиная с 0 для перво-
го элемента. Можно использовать как положительные, так и отрицательные
индексы; положительные отсчитываются от начала списка (0,1,2 и т. д.), а от-
рицательные — от конца (-1 для последнего элемента, -2 для предпоследнего
и т. д.).
Давайте рассмотрим пример списка и как обращаться к его элементам
с помощью индексов и срезов:
# Создаем список с автомобилями
cars = ["Toyota", "Ford", "BMW", "Honda", "Hyundai", "Mercedes",
"Audi"]
ff Доступ к элементам по индексу
print("Доступ к элементам:")
print(cars[1]) # Выводит: Ford
print(cars[-1]) # Выводит: Audi
# Срезы
print("\nСрезы элементов:")
print(cars[::2]) # Выводит: ['Toyota', 'BMW', 'Hyundai', 'Audi']
print(cars[l::2]) # Выводит: ['Ford', 'Honda', 'Mercedes']
print(cars[2:5]) # Выводит: ['BMW', 'Honda', 'Hyundai']
print(cars[-3:-6:-l]) # Выводит: ['Hyundai', 'Honda', 'BMW']
t Проверка на наличие в списке
print("\пПрсверка на наличие элемента в списке:")
if "Ford" in cars:
print("Ford есть в списке!")
else:
print("Ford нет в списке.")
ff Замена элемента на индексе 2 (5MW) на "Tesla"
print("\пЗамена элемента:")
cars[2] = "Tesla"
print (cars) # Выводит: ['Toyota', 'Ford', 'Tesla', 'Honda', 'Hyundai.',
'Mercedes', 'Audi']
# Замена диапазона значений
print ("\г.3амена диапазона значений:")
cars[l:4] = ["Chevrolet", "Kia", "Nissan"]
print(cars) # Выводит: ['Toyota', 'Chevrolet', 'Kia', 'Nissan',
'Hyundai', 'Mercedes', 'Audi']
Объяснение:
1. Мы создали начальный список cars, содержащий названия автомобилей.
2. Доступ по индексу:
• print (cars [1]) печатает второй элемент списка — "Ford";
• print (cars [-1]) печатает последний элемент списка—"Audi".
3. Срезы:
• cars [:: 2 ] печатает каждый второй элемент в списке, начиная с первого
(индекс 0);
• carsfl: :2] печатает каждый второй элемент, начиная со второго (ин-
декс 1);
• cars[2:5] печатает элементы с третьего (индекс 2) по пятый (индекс
4);
• cars[-3:-6:-l] печатает элементы с конца в обратном порядке, вклю-
чая "Hyundai", "Honda" и "BMW".
4. Проверяем, есть ли "Ford" в списке.
5. Заменяем элемент на индексе 2 (BMW) на "Tesla".
6. Заменяем элементы с индексами от 1 до 3 на новые значения ("Chevrolet",
"Kia", "Nissan").
Этот пример демонстрирует работу со списками автомобилей, включая
доступ к элементам, операции замены и проверки.
Методы работы со списками
Списки обладают множеством встроенных методов, которые позволяют
удобно управлять их содержимым.
Метод insert () используется для вставки элемента в список по заданному
индексу.
Синтаксис:
list.insert(index, element)
Используется для добавления элемента в список на указанную позицию.
• list — это имя списка, к которому мы хотим добавить новый элемент.
• insert — это метод, который инициирует добавление элемента в спи-
сок. Он позволяет поставить элемент на определенную позицию, что
отличает его от метода append(), который добавляет элемент только
в конец списка.
* index — это позиция (или индекс) в списке, где вы хотите вставить но-
вый элемент. Индексы начинаются с 0, то есть index С указывает на
первый элемент списка, index 1 — на второй элемент и т. д. Если ука-
зать индекс больше текущего размера списка, элемент будет добавлен
в конец.
♦ element — это значение, которое мы хотим добавить в список. Оно мо-
жет быть любого типа: числом, строкой, списком и т. д.
В результате вызова list.insert (index, element) элемент будет вставлен
в список на указанную позицию, а все последующие сдвинутся вправо на од-
ну позицию. Например, если вставить элемент на индекс 1, он займет вторую
позицию, а все элементы, находившиеся ранее на позициях 1 и далее, пере-
местятся на одну позицию вправо.
Пример:
f Создаем список с названиями книг
books = ["1984", "Фауст", "Отверженные", "Война и мир"]
books.insert(2, "Анна Каренина")
# Вставляем "Анна Каренина" на индекс 2
print(books)
# Выводит:
['1984', 'Фауст', 'Анна Каренина', 'Отверженные', 'Война и мир']
Метод append () добавляет элемент в конец списка.
Синтаксис:
list.append(element)
Он используется для добавления элемента в конец списка.
• list — это имя списка, к которому мы хотим добавить новый элемент'.
Список может содержать разные типы данных — числа, строки, другие
списки и прочие объекты Python.
• append — это метод, который позволяет добавить новый элемент в ко-
нец списка. Он изменяет исходный список, добавляя элемент к его ха-
рактеристикам без создания нового списка.
• element — это значение, которое мы хотим добавить в список. Элемент
может быть любого типа: числом, строкой, списком или любым другим
объектом.
Когда вы вызываете list .append (element), элемент добавляется в конец
списка. Например, если список содержит три элемента и вызывается list.
append (new_element), новый элемент станет четвертым.
Стоит отметить, что метод append () не возвращает никаких значений, по-
этому он используется исключительно для изменения содержимого списка
«на месте».
Пример:
books.append("Братья Карамазовы")
# Добавляем "Братья Карамазовы" в конец списка
print(books)
# Выводит:
['1984', 'Фауст', 'Анна Каренина', 'Отверженные', 'Война и мир',
'Братья Карамазовы']
Метод extend () используется для добавления элементов из другого списка.
Синтаксис:
list.extend(iterable)
Он используется для добавления всех элементов из другого итерируемо-
го объекта, который можно перебрать (например, списка, кортежа, строки),
в конец существующего списка.
• list — это имя списка, к которому вы хотите добавить элементы.
• extend — это метод, который позволяет расширить существующий
список, добавляя в него элементы из другого итерируемого объекта.
В отличие от метода append (), который добавляет один элемент в конец
списка, extend () добавляет каждый элемент из итерируемого объекта
по отдельности.
• iterable — это любой итерируемый объект (например, список, кортеж,
строка или даже другой список). Каждый элемент из этого объекта до-
бавляется в конец исходного списка.
Когда вы вызываете list.extend(iterable), все элементы из переданного
итерируемого объекта добавляются в конец списка один за другим. Например,
если вы вызываете list.extend([4, 5, 6]) для списка с тремя элементами,
сформируется список из шести элементов, в котором новые элементы добав-
лены в том же порядке, в каком они поступили из итерируемого объекта.
Метод extend () изменяет исходный список «на месте» и не возвращает
никаких значений, что делает его удобным для добавления нескольких эле-
ментов сразу.
Пример:
more_bocks = ["451 градус пс Фаренгейту", "Темные начала"]
books.extend(more books) # Добавляем элементы другого списка
print(books)
# Выводит:
['1984', 'Фауст', 'Анна Каренина', 'Отверженные', 'Война и мир',
'Братья Карамазовы', '451 градус по Фаренгейту', 'Темные начала']
Метод remove () удаляет первое вхождение указанного элемента из списка.
Синтаксис:
list.remove (element)
Используется для удаления первого вхождения указанного элемента из
списка.
• list — это имя списка, из которого мы хотим удалить элемент.
• remove — это метод, который инициирует удаление элемента из списка,
находя первое совпадение с указанным значением.
* element — это значение, которое мы хотим удалить из списка. Если эле-
мент присутствует в списке, метод remove () найдет первое его вхож-
дение и удалит его. Важно отметить, что метод использует оператор
равенства (=-) для поиска совпадений.
Пример:
books.remove("Война и мир") Д Удаляем "Война и мир" из списка
print(books)
# Выводит:
['1984', 'Фауст', 'Анна Каренина', 'Отверженные', 'Братья Карамазовы',
'451 градус по Фаренгейту', 'Темные качала']
Метод pop () удаляет элемент по заданному индексу и возвращает его. Ес-
ли индекс не указан, он удаляет и возвращает последний элемент.
Синтаксис:
list.pop(index)
Используется для удаления элемента из списка по заданному индексу
и возвращения этого элемента.
• list — это имя списка, из которого вы хотите удалить элемент.
• pop — это метод, который инициирует удаление элемента из списка по
указанному индексу. Он не только удаляет элемент, но и возвращает
его, что позволяет использовать это значение в дальнейшем.
• index — это позиция (или индекс) элемента, который вы хотите уда-
лить. Индексы начинаются с нуля, то есть индекс 0 указывает на пер-
вый элемент списка, индекс 1 — на второй и т. д. Если индекс не указан,
метод pop () удалит и вернет последний элемент списка. Если указан-
ный индекс находится вне диапазона возможных индексов списка (на-
пример. отрицательное значение или больше, чем размер списка), бу-
дет возбуждено исключение IndexError.
Когда вы вызываете list.pop (index), элемент, находящийся на указанной
позиции, удаляется из списка, а все последующие сдвинутся влево, чтобы за-
нять его место. Этот метод позволяет удобно извлекать элементы из списка
и работать с ними после удаления.
Пример:
last_bcok = books.pop() (f Удаляем и возвращаем последний snetzeHT
print(last bock)
# Выводит: Темные начала
print(books)
# Выводит: 1'1984', 'Фауст', 'Анна Каренина', ’Отверженные',
'Братья Карамазовы', '451 градус по Фаренгейту']
Метод clear () удаляет все элементы из списка.
Синтаксис:
list.clear()
Используется для удаления всех элементов из списка, в результате чего он
становится пустым.
• list — это имя списка, который вы хотите очистить.
* clear — это метод, который инициирует процесс очистки списка. Ис-
пользуя его, вы удаляете все элементы без необходимости обращаться
к ним по отдельности.
Когда вы вызываете list. clear (), все элементы в списке удаляются, и спи-
сок становится пустым (то есть его длина равна нулю). Этот метод изменяет
исходный список «на месте», не создавая нового списка, и не возвращает ни-
каких значений.
Пример:
books.clear() # Очищаем список
print(books)
# Выводит: []
Метод sort() сортирует элементы списка на месте. Сначала элементы
должны быть сопоставимы друг с другом.
Синтаксис:
list.sort ()
Используется для сортировки элементов существующего списка на месте,
изменяя порядок их расположения.
• list — это имя списка, который вы хотите отсортировать. Список мо-
жет содержать элементы различных типов данных, однако для коррек-
тной сортировки все элементы должны быть сопоставимыми (напри-
мер, все должны быть числами или строками).
• sort — это метод, который инициирует процесс сортировки элементов
в списке. Он изменяет исходный список, расставляя элементы в поряд-
ке возрастания по умолчанию. При необходимости вы можете задать
порядок сортировки (по убыванию) и использовать пользовательские
функции для сортировки.
По умолчанию метод sort() сортирует элементы в порядке возрастания.
После вызова этого метода список будет перестроен и элементы расположат-
ся в отсортированном порядке.
Кроме того, метод sort () может принимать два параметра.
1. reverse — булевый параметр, который при установке в True меняет по-
рядок сортировки на убывающий.
2. key — функция, которую можно использовать для извлечения значения
для сортировки из каждого элемента.
Пример:
numbers = [3, 1, 4, 1, 5]
numbers.sort() fr Сортируем список чисел
print(numbers)
I Выводит: [1, 1, 3, 4, 5j
Методы работы со списками предоставляют .мощные инструменты для
управления содержимым списков. Вы можете добавлять, удалять, изменять
и сортировать элементы списка, что позволяет создавать динамические
и гибкие структуры данных.
Выводы
В главе рассмотрены ключевые структуры данных Python — строки и слова-
ри, — их свойства, способы создания и основные методы работы. Ниже —
структурированные итоговые тезисы.
1. Строки (str)
Основные характеристики
• Предназначены для хранения и обработки текстовой информации.
• Упорядоченная последовательность символов с индексацией (поло-
жительной и отрицательной).
• Неизменяемы: модификация требует создания новой строки.
Способы создания
• Одинарные кавычки: <текст>.
* Двойные кавычки: «текст».
• Тройные кавычки (для многострочных строк):
python
multi_line = «»»Строка
на несколько
строк.»»»
Индексация и срезы
• Индексы: от 0 (первый символ) до -1 (последний символ).
• Синтаксис среза: string[start:slop:stepj.
• Примеры:
text[::2] — каждый второй символ;
text [::-!] — строка в обратнохМ порядке.
Основные операции
• Конкатенация: strl + str2.
• Повторение: str * и.
• Определение длины: len(string).
Форматирование строк
• f-строки (рекомендуемый способ): Б>Имя: {name}».
• Метод .format(): «Имя. {}”.formal(name).
Ключевые методы
• .lower(), .upperf) — изменение регистра.
• .replace(old, new) — замена подстроки.
• .split(delimiter) — разбиение на список.
• .join(ilerable) — объединение элементов в строку.
• .fmd(substring) — индекс первого вхождения.
• .count(substring) — число вхождений.
• .strip([chars]) — удаление пробелов/символов по краям.
2. Словари (diet)
Основные характеристики
• Неупорядоченные коллекции пар «ключ: значение».
• Ключи: уникальны, неизменяемы (строки, числа, кортежи).
• Значения: могут быть любого типа, включая вложенные структуры.
• Обеспечивают быстрый доступ к данным по ключу (на основе хеш-
таблицы).
Способы создания
1. Через фигурные скобки:
python
my_dict = {‘ключГ: 'значение!’, ‘ключ2’: ‘значение2’}
2. Через функцию dict():
Именованные аргументы: dict(co6aKa=3, кошка=4).
Список кортежей: dict([(<a>, 1), (<h>, 2)]).
3. Пустой словарь: {} или dict().
Работа с элементами
• Доступ по ключу: ту_б1с1[<ключ>] (при отсутствии ключа —
КеуЕггог).
• Безопасный доступ: my_dict.get(<Kmo4>, default).
• Обновдение/добавление: ту_<Нс1|<ключ>] = новое_значение.
• Удаление:
.рор(ключ) — удаляет ключ и возвращает значение.
.clear() — очищает словарь.
Ключевые методы
• .keys() — итератор по ключам.
• .values() — итератор по значениям.
• .itemsO — итератор но парам «ключ-значение» (удобно для циклов).
• .update(other_dict) — массовое обновдение/добавление нар.
• .сору() — поверхностная копия словаря.
• dict.fromkeysfkeys, default) — создание словаря с одинаковыми значе-
ниями.
Вложенные структуры
• Поддерживают вложенные словари, списки, множества, кортежи,
функции.
• Пример:
python
profile = {
‘name’: ‘Иван’,
‘age: 30,
'hobbies’: [‘чтение’, ‘плавание’]
}
• Доступ: nested_dict[<^HBOTHbie»] [«собака»].
Специальные возможности
• defaultdict (из collections): автоматически присваивает значение по
умолчанию для отсутствующих ключей.
• Генераторные выражения:
python
cubed_dict = {х: х**3 tor х in range(5)}
• Порядок ключей (Python 3.7+): сохраняется порядок вставки.
3. Комбинированные структуры и типы значений
Булевы значения
• Используются как логические флаги (True/False).
• JI римеры.
python
{‘is_student’: True, ‘is_employee’: False}
• Применение: статусы, переключатели, результаты проверок.
Списки в значениях
• Хранят упорядоченные коллекции элементов.
• Пример: {<fruits>: [<apple>, <banana>]}.
• Доступ: dict[<fruits>]|0].
Кортежи в значениях
• Неизменяемые упорядоченные коллекции.
• Пример: {^coordinates»: (10.5, 20.3)}.
• Применение: координаты, пары значений, ключи индексов.
Множества в значениях
* Неупорядоченные коллекции уникальных элементов.
• Пример: {<unique_numbers>: {1, 2, 3}}.
• Применение: уникальные теги, ID, операции над множествами.
Функции как значения
• Позволяю! хранить «контейнеры поведения».
• Пример:
python
def greet(name): return f”Hello, {name}!”
{'greeting_function\ greet}
• Вызов: dict[«key>](arguments).
4. Итоговые выводы и рекомендации
Общие принципы
1. Строки:
Фундаментальный тип для текста.
Неизменяемость требует создания новых строк при модификации.
Методы и срезы обеспечивают мощную обработку.
2. Словари:
Эффективный способ организации данных с доступом по ключу.
Поддерживают сложные вложенные структуры.
Оптимизированы для быстрого поиска (хеш-таблица).
3. Философия Python:
Простота синтаксиса (dict[key], str| 0}).
Богатый набор встроенных методов.
Гибкость для решения задач любой сложности.
Рекомендации по применению
1. Для строк:
Используйте f-строки для форматирования.
Применяйте срезы для извлечения подстрок.
Учитывайте неизменяемость при модификации.
2. Для словарей:
Используйте .get() для безопасного доступа к значениям.
Применяйте .update() для массового изменения данных.
Копируйте словари через .сору(), если требуется изоляция изменений.
Используйте defaultdict для автоматического создания значений.
Комбинируйте типы значений (списки, кортежи, множества) для
компактности.
3. Для вложенных структур:
Вложенные словари — для иерархических данных (профили, конфи-
гурации).
Списки — для упорядоченных коллекций.
Кортежи — для неизменяемых групп (координаты, параметры).
Множества — для уникальных элементов.
4. Для производительности:
Избегайте изменения словаря во время итерации.
Используйте . items () для обработки пар «ключ-значение».
Предпочитайте sort () вместо sorted (), если не нужно сохранять ори-
гинал.
5. Для безопасности:
Проверяйте наличие ключей через in перед доступом.
Обрабатывайте исключения для .рор() и . remove ().
Выбирайте неизменяемые типы (кортежи) для данных, которые не
должны меняться.
5. Заключение
• Строки — незаменимый инструмент для работы с текстом, сочетаю-
щий простоту и мощь обработки.
• Словари — универсальный механизм для хранения и организации
данных, поддерживающий:
- быстрый доступ по ключу;
- вложенные структуры любой сложности;
- динамическое поведение (хранение функций);
- интеграцию с JSON и API.
• Комбинация структур (например, список кортежей или словарь со
списками) позволяет моделировать реальные данные с высокой гиб-
костью.
Глава 6
Инженерия данных:
манипуляции с файлами
и каталогами
В этой главе мы рассмотрим процесс работы с файлами и каталогами. Основ-
ное внимание уделим следующим аспектам:
1. Чтение и запись файлов. Узнаем, как открывать, читать, записывать
и закрывать файлы, а также рассмотрим различные режимы работы с ними
(например, текстовые и бинарные).
2. Обработка банных. Разберем работу с данными в файлах, включая пар-
синг, модификацию содержимого и обработку ошибок при работе с файло-
выми операциями.
3. Работа с каталогами. Изучим методы создания, удаления и изменения
каталогов, а также перечислим их содержимое.
4. Использование стандартной библиотеки. Подробно опишем модули
и функции стандартной библиотеки Python, такие как cs, shutil и pathlib,
которые облегчают манипуляции с файлами и каталогами.
5. Практические примеры. Покажем наглядные примеры и задачи для за-
крепления навыков работы с файлами и каталогами, а также дадим советы по
эффективной организации данных.
Эта глава поможет вам овладеть навыками, необходимыми для управле-
ния данными и файлами в Python, что является важной частью работы в об-
ласти инженерии данных.
Текстовые файлы
Фундаментальные аспекты работы с файлами
В основе хранения и передачи данных лежат файлы, предст авляющие собой
структурированные последовательности байтов. В Python для манипуляции
файлами используется встроенная функция ореп(), обеспечивающая интер-
фейс для открытия и закрытия файлов.
Режимы доступа к файлам:
• 'г' (чтение) — стандартный режим, открывающий файл для чтения
данных;
• 'w' (запись) — режим, перезаписывающий существующий файл или
создающий новый, если файл с указанным именем отсутствует;
• 'а' (добавление) — режим, добавляющий данные в конец файла, не из-
меняя его содержимое;
• 'г+' (чтение и запись) — режим для чтения и записи данных в файл;
• 'Ь' (бинарный режим) — режим для работы с нетекстовыми данными,
такими как изображения или аудиофайлы.
Чтение текстового файла
Перед тем как открывать файл в программной среде, нужно загрузить его
в каталог рядом с файлом Python (кнопка «Загрузить в сессионное храни-
лище»).
Создадим текстовый файл example.txt с несколькими записями и загру-
зим его в Google Colab.
О X
ШЛС «з£ГО) в«(У) «Й(Н.
Первая строк» текста.
Вторая строка текста.
Третья строка текста.
Четвертая строка текста.
Ж «И 100* Windows(СЙ1Р) UTF-B
Рис. 6.1
В данном случае файл загружен в основной каталог.
В Python J
Рис 6.2
Контекстный менеджер with гарантирует корректное закрытие файла пос-
ле выполнения операций, что важно для безопасного программирования.
t Указываем полный путь к файлу
file_path = '/content/example.txt'
# Открываем файл и читаем его содержимое
with open(file_path, 'г', encodings'utf-8') as file_handle:
content = file_handle.read() ff Чтение всего содержимого файла
print("Содержимое всего файла:")
print(content) # Вывод содержимого
f Считываем файл построчно
with cpen(file path, 'г', encoding®'utf-8') as file_handle:
lines = file_har.dle.readlines () # Чтение файла построчно
print("\пСодержимое файла построчно:")
for line in lines:
print(line.strip()) # Вывод каждой строки без лишних пробелов
[1, 1. 3. 4, 3]
Q • . д»оа б
dqhwA путь к файлу
filtjMth • ‘/corttent/swnpledaf/Bx—ple. txt •
« Открываем файл и читаем его содержимое
with open(flle_path, 'r‘, encoding-utf-8') as file_haodle:
content • flle_handle.read() • чтение всего содержимого файла
print(’Содержимое всего файла:”)
print(content) о Вывод содержимого
в Считываем файл построчно
with open(fllej>athJ 'г* *, encoding-'utf-8') as file_handle:
lines - flle_handle.r»*dlln»s() • Чтение файла построчно
print("\nCодержимо» файла построчно:’)
for line In lines:
print(line.strip()) • Вывод каждом строки 6es лмамих про6елое|
... Содержимое всего файла:
Первая строка текста.
Вторая строка текста.
Третья строка текста.
Четвертая строка текста.
Содержимое файла построчно:
Первая строка текста.
Вторая строка текста.
Третья строка текста.
Четвертая строка текста.
а Указываем полный путь к файлу
file_path • */content/s<wpledata/exaBple.txt*
* Содержимое для записи в файл
content • [
’Первая строка текста 1.\п’,
Рис. 6.3
Этот код сначала читает весь текст из файла и выводит его, а затем читает
файл построчно и выводит каждую строку отдельно.
Давайте разберем каждую строку кода:
with open('example.txt', 'r', encodingsutf-8') as file handle:
1. with cpen(..Оператор with используется для автоматического уп-
равления ресурсами. Он открывает файл и гарантирует, что тот будет закрыт
после выхода из блока with, даже если в процессе возникнет ошибка.
2. 'example.txt' — имя файла, который мы хотим открыть. В данном слу-
чае это текстовый файл с именем example. txt.
3. 'г' — режим открытия файла. < г > означает, что файл открывается в ре-
жиме чтения (read). Значит, мы можем только читать содержимое файла, но
не изменять его.
4. encodings'utf-8' указывает, что файл следует читать с использованием
кодировки UTF-8. Это важно для обеспечения корректного чтения текстов
с символами, выходящими за пределы ASCII
5. as file_handle задает имя переменной (file handle), с помощью кото-
рой мы будем обращаться к открытому файлу внутри блока with.
content = file handle.read() # Чтение всего содержимого файла
6. content = file handle.read(). С помощью метода read() происходит
чтение всего содержимого файла и сохранение его в переменной content. Те-
перь она содержит текст из всего файла.
lines = file handle.readlines()
s Чтение файла пс строкам, результат - список строк
7. lines = file_handle.readlines () вызывает метод readlines (), который
читает файл построчно и возвращает список строк. Каждая строка стано-
вится отдельным элементом списка lines. Важно отметить, что на этом этапе
происходит ошибка, поскольку файл уже был прочитан с помощью read()
и его указатель находится в конце файла. Чтобы метод работал корректно,
его нужно вызывать до read () или переместить указатель в начало файла (с
помощью f ile_handle.seek (0)), если вы хотите прочитать файл снова.
Обратите внимание на комментарии в коде, которые поясняют действия
каждой строки.
Запись данных в файл
« Указываем полный путь к файлу
file_path = '/content/example.txt'
# Содержимое для записи в файл
content = (
"Первая строка текста 1.\п",
"Вторая строка, текста 2.\п",
"Третья строка текста З.\п",
"Четвертая строка текста 4.\п"
# Записываем данные в файл
with open (file_pat.h, 'w', encodings'utf-8') as file_handle:
file handle.writ elines(content) # Запись всех строк в файл
print("Данные успешно записаны в файл:", file_path)
# Считываем файл построчно
with openffile path, 'г', encoding-'utf-8') as file_handle:
lines = file_har.dle.readlines () # Чтение файла построчно
print("\пСодержиыое файла построчно:")
for line in lines:
print(line.stripO) # Вывод каждой строки без лишних пробелов
with op«n(‘lsslng_flle.txt') as fllc.handlc:
print(fi1a_h*hd1•.read())
«except filaHotFoundErtw:
print("аайл w найдем!")
Рис. 6.4
Табл. 6.1
Код Пояснение
# Указываем полный путь к файлу file_path = '/content/example.rxt' Задаем переменную file path, которая содержит путь к файлу example. txt-Это путь, по которому будет создан или найден файл
* Содержимое для записи в файл content = [ "Первая строка текста 1.\п", "Вторая строка текста 2.\п", "Третья строка текста З.\п", "Четвертая строка текста 4.\п"] Создаем список content, содержащий строки текста, которые вы хотите записать в файл. Каждая строка заканчивается символом новой строки (\п), который обеспечивает правильный перенос строк в файле
S Записываем данные в файл with cpen(file_path, 'w', encoding3'utf-8') as file_handle: file_handle.writelines(content) * Запись всех строк в файл with open(file_path, V, encoding3'utf-8') as file handle — команда для открытия файла, указанного в file_path, в режиме записи (V). Если файла не существует, он будет создан; в ином слу- чае предыдущие данные перезапишутся. Аргумент encoding3' utf-8' указывает, что файл использует кодировку UTF-8, что позволяет корректно записы- вать символы. file_handle.writelir.es(content) записывает все строки из списка content в файл Метод writelines () объединяет строки и записывает их одной операцией
print("Данные успешно записаны в файл:", file_path) Выводим в консоль сообщение о том, что данные успешно записаны в файл. Это помогает понять, что процесс завершен
# Считываем файл построчно with open(fiie_pach, 'г', encoding3'utf-E') as file_handle: lines = file_nandle.readlines() r Чтение файла построчно Снова открываем файл, теперь в режиме чтения ('г'). Это позволяет прочитать его содержимое, lines = file_handle. readlines О читает весь файл построчно и сохраняет эти строки в список lines
Код Пояснение
print("\пСодержимое файла пост- рочно :") for line in lines: print(line.strip()) « Вывод каж- дой строки без лишних пробелов print("\пСодержимое файла построчно:") выводит заголовок перед выводом содержимого файла. Цикл for line in lines: перебирает каждую стро- ку в списке lines. print (line.strip ()) выводит каждую строку в кон- соль, убирая лишние пробелы (включая символы новой строки) с помощью метода strip(). Это делает вывод более аккуратным
Код создает текстовый файл, записывает в него несколько строк, а затем
считывает и выводит содержимое файла построчно. Запись и чтение — это
основные операции работы с файлами в Python.
Обработка исключительных ситуаций
при работе с файлами
Для предотвращения ошибок при работе с файлами рекомендуется исполь-
зовать блок try-except [82], который перехватывает и обрабатывает исклю-
чения, такие как FileNotFoundError, возникающие при попытке открыть не-
существующий файл.
try:
with open('missing file.txt') as file handle:
print(file handle.read())
except FileNotFoundError:
print("Файл не найден!")
"ч»тн(п« строк* г*кста 4.\п"
)
• Залисьмам дайны» файл
with ор»Щ# il»_path, •»', tncodlnf>'utf-в') as fil«_handl*:
fll»_haadl».Mrlt»lln»s(co«it»flt) • Запись всех строя файл
print ("Да*»** успсямо записаны а файл;-, fil«_p*th)
• С w ту» It* файл псх трочно
with op»n(fii«_path. ‘г*, »ncodine-‘utf-8’) as fil«_hondlo:
lino» - fil»_handi».r»*dlin»t() а Чт«*и« файла построчно
print ('\jr>C<WP»’**=* построй»;J)
for line In linos.
prinx(lift».strip()) V «мши **«АОЙ строк» 6»э дума пробало»
Данин» условно в**мсм • файд: /com»nt/saepi»_data/»xawpl*.txt
СОдерято» 9»ил* построчно:
Лерам стром т««ста 1.
вторая стром тн<н 2.
Третья стром текста 3.
ч*т»«рт«я строк» текста 4.
О шг:
with opMCBisiin&.fllt.txt*) as fllt.MMl»:
print(fil»_handl».r»adJ)
axeypt И lemotfoundCrror:
print (~4аФл н» найден!")
••• ваяя w« найден!
lyort csv
а чтами» даммос ai CSV файла
with op»n('/content/Pata(l).csv', V, ♦ncosing.utf-»') »s csvfllt;
reader - csv.reader,csvf11»)
Давайте подробно разберем этот код, который демонстрирует обработку
исключений при работе с файлами:
1. try: — начало блока try, который обрабатывает возможные ошибки,
возникающие в его пределах. Любой код внутри этого блока проверяется на
наличие исключений.
2. with open ('missing_file.txt') as file handle: — попытка открыть
файл с именем missing_file.txt с помощью оператора with. Если файл су-
ществует, он откроется, и переменная file_handle будет содержать объект,
представляющий этот файл. Если же его не существует, возбуждается исклю-
чение FileNotFoundError, и выполнение переходит к блоку except.
3. print (f ilejiandle. read ()). Если файл успешно открыт, эта строка будет
выполнена. Метод read() читает все содержимое файла и выводит его на эк-
ран. Однако, если файл не найден, эта строка не будет выполнена и управле-
ние сразу перейдет к блоку except.
4. except FileNotFoundError:. Блок except срабатывает, если в блоке try
возбуждено исключение FileNotFoundError. Это исключение возникает, если
программа пытается открыть несуществующий файл.
5. рг1пЦ"Файл не найден!"). Если файл missinq_fiie.txt не найден, эта
строка будет выполнена, и на экран выведется сообщение "Файл не найден!".
Это позволяет узнать, что произошла ошибка при попытке открыть файл.
Приведенный код пытается открыть файл, и, если он не существует, код
обрабатывает это исключение, выводя сообщение об ошибке. Таким образом,
код защищен от сбоев, связанных с отсутствием файла.
Манипуляции со структурированными данными
Форматы данных: CSV, JSON, XML
Для эффективной работы с табличными данными широко используются
форматы CSV (Comma-Separated Values) и JSON ( JavaScript Object Notation),
а для обработки структурированных документов — XML (extensible Markup
Language).
Формат CSV
Модуль CSV предоставляет инструменты для работы с табличными дан-
ными, представленными в формате .csv.
Чтение CSV-файла
CSV-файл, что переводится как «значения, разделенные запятыми», — это
простой текстовый файл, который используется для хранения табличных
данных.
1. Строки и столбцы. CSV-файл можно представить как таблицу, где дан-
ные размещаются в строках и столбцах. Каждая строка — это отдельная за-
пись (или строка данных). Значения в ней разделяются запятой (иногда дру-
гим символом, например точкой с запятой).
2. Простой текст. CSV-файл состоит только из текстовой информации,
поэтому его легко открыть и редактировать с помощью простых текстовых
редакторов, таких как «Блокнот». Также он открывается в программах для
работы с таблицами, например Microsoft Excel или Google Sheets, где данные
отображаются в виде таблицы.
Создадим файл data (1) .csv со следующими данными:
Файл Главная Вставка Рисование Разметка ст] Формулы Да»
А1 * > -У fx Title,Author, Pages, Weight, Ри
А В C D E F
1 I Kle,Author,Pages,Weight,Put>lisbedYear
2 1984,"George Orwdl‘,328,0.30,1949
3 To Kill a Mockingbird,“Harper Ue" 281,0.25,I960
4 The Great Gatsby/F. Scott FiugeralcF.l80,0.22,1925
5 The Catcher in the Rye,’J.D Salinger".277,0.32,1951
6 Brave New World,"Aldous Huxley*^11,0.28,1932
7 Pride and Prejudice.’Jane Austen",432,0.35,1813
8 The Hobbit,"J.R.R. Tolkien",310,0.40,1937
9 Fahrenheit 451,"Ray Bradbury*1,!58,0.18,1953
10 The Akhemist.-Paulo Coelho",208,0.24,1988
11 The Picture of Dorian Gray,"Oscar Wilde" Д54,0.26,1890
12 The Secret Gerdc-n/Frences Hodgson Burnett",331,0.29,1911
13 Brave New World Revisited,"Aldous Ниж1су",184,0.22,1958
14 Animal Farm,"George Orwell", 112,0.15,1945
15 The Kite Runner.'Khaled Hosseini",372.0.33.2003
16 Ufe of Pi.’Yann Martel",319,0.30,2001
17
Рис. 6.6
import csv
? Чтение данных из CSV файла
with open('data (l).csv', 'r', encodings'utf-8') as csvfile:
reader = csv.reader(csvfile)
next(reader) # Пропускаем заголовки
for row in reader:
if len(row) >= 2: # Проверяем, что строка содержит как минимум
2 элемента
print(row[0], row[l]) # Доступ к значениям столбцов по ин-
дексам
else:
print("Пустая строка или недостаточно столбцов:", row) #
Выводим пустые строки
with орел(’elssingf ile.txt ’) as file_h*ndle:
pr 1 nt (f 1 l«_hand 1 *. r*»d ())
Т.Х5УР1 FileNotFound Error:
print("Файл we нейдем!')
«айл не найден!
О <sv
а чтение дагвякх иг CSV файгЦ
with open(‘/content/data(l).csv', ‘r‘, encoding*'utf »') as csvfile:
reader - csv.reader(csvfile)
next (reader) • пропуска*** аагоиоекм
for row in reader:
if len(row) >» 2: • Провернем, что строка содержит как мнмичум 2 элемента
print(row[8), row[l]) • Доступ к змячвнв** столбцов по индексам
else:
print("Пустея строка млн недостаточно столбцов:", row) • Ё»гсд>** пустые строки
••• Пустая строка мл* недостаточно столбцов: (”1984,’George Orwell",328,6.30,1949 *]
Пустая строка или недостаточно столбцов: (' То Kill a Mockingbird,"Harper Lee”,281,в.25,1960 *)
Пустая строка или недостаточно столбцов: (' The Great Getsby,”F. Scott Fitzgerald",188,8.22,1925 ’]
Пустая строка или недостаточно столбцов: (‘ The Catcher in the Rye,"J.0. Salinger*,277,0.32,1951 *]
Пустая строка млн недостаточно столбцов: (’ Brave New World,"Aldous Huxley”,311,0.28,1932 ’]
Пустая строка или недостаточно столбцов: (* Pride and Prejudice,"Jane Austen",432,0.35,1813 *]
Пустая строка или недостаточно столбцов: (* The Hobbit,“J.R.R. Tolkien",310,8.40,1937 ’)
Пустая строка или недостаточно столбцов: (’ Fahrenheit 451,"Rey Bradbury",158,8.18,1953 'J
Пустая строка или недостаточно столбцов: (' The Alcheeist,"Paulo*J
Пустая строка или недостаточно столбцов: (' Coelho",2М,0.24,1988 *)
Пустая строка или недостаточно столбцов: (' The Picture of Dorian Gray,”Oscar*)
Пустая строка или недостаточно столбцов: HiIde",254,0.26,1899 ']
Пустая строка или недостаточно столбцов: (' The Secret Garden,"Frances Hodgson')
Пустая строка или недостаточно столбцов: (’ Burnett",331,8.29,1911 ']
Пустая строка или недостаточно столбцов: (‘ Brave New World Revisited,"Aldous Huxley”,184,8.22,1958 •)
Пустая строка или недостаточно столбцов: (' Anleal Fare,"George Orwell”,112,в.15,1945 ')
Пустая строка или недостаточно столбцов: [' The Kite Runner,"Khaled Hosseini",372,8.33,2883 ']
Пустая строка или недостаточно столбцов: (' Life of Pi,“Yann Hertel", 319,8.38,208Г)
ieport csv
Рис. 6.7
Табл. 6.2
Код Пояснение
Импорт модуля csv: import csv Импортируем модуль csv, который предоставля- ет функции для работы с файлами в формате .csv
Открытие CSV-файла: with open('data (l).csv', ’r', encodingsutf-8') as csvfile: open('data (l).csv', 'г', encodings'utf-8') открывает файл data (1) .csv в режиме чтения ('г'), encodingsutf-8' гарантирует, что файл будет корректно прочитан, даже если содержит символы из различных языков as csvfile — присвоение открытого файла пере- менной csvfile, чтобы мы могли с ним работать в дальнейшем
Создание объекта reader: reader = csv,reader(csvfile) Создаем объект reader, который считывает стро- ки из CSV-файла Каждая строка представляется как список значений, разделенных запятыми
Пропуск заголовков: next (reader) # Пропускаем заголовки Метод next (reader) используется для пропуска первой строки в CSV-файле (заголовков), чтобы не обрабатывать их как данные
Перебор строк в файле: for row in reader: Этот цикл проходит по каждой строке (каждому списку значений) в объекте reader
Проверка длины строки: if len(rcw) >= 2: # Проверяем, что строка содержит как минимум 2 элемента Условие проверяет, содержит ли текущая строка (список) как минимум 2 элемента. Это важно, поскольку мы собираемся обращаться к первым двум элементам
Вывод первых двух значений: print(row[С], row[1]) # Доступ к значениям столбце в по индексам Если строка содержит достаточное количество элементов, программа выводит на печать значе- ния первого (row[0]) и второго (row(1]) столбцов,
Код Пояснение
Вывод пустых строк и строк с недостаточным количеством столбцов: else: print("Пустая строка или не- достаточно столбцов:", row) f Выводим пустые строки Если строка не содержит минимум 2 элемента, программа выводит сообщение о том, что она пуста или что там недостаточно столбцов, имеете с содержимым этой строки
Основная цель этого кода — прочитать и вывести данные [83] из файла
data (1) .csv, игнорируя первую строку (заголовки), и избегать ошибок, свя-
занных с отсутствием данных, путем проверки длины каждой строки. Если
строка не проходит проверку, программа сообщает об этом вместо заверше-
ния с ошибкой.
Для удобства работы с данными, представленными в виде словаря, можно
использовать метод DxctReader.
import csv
with cper.('aata (l).csv', 'r', encodings utf-8') as csvfile:
reader = csv.DictReader(csvfile)
# Удаляем пробелы из заголовков
reader.fieldnar.es = [name.str ip () for name in reader.fieldnames)
for row in reader:
print(row['Title'], row[ 'Author'])
Пуст** строк* или недостаточно столбцов: ['
Пустая строке или недостаточно столбцов; (’
Пуст** строк* или недостаточно столбцов: ('
Пустая строка или недостаточно столбцов: [’
пустая строка или недостаточно столбцов: ('
Пустая строка или недостаточно столбцов: ['
пустая строк* или недостаточно столбцов: ['
Пустая строка или недостаточно столбцов: [’
Пустая строка или недостаточно столбцов: [*
Coelho* *,298,8.24,1988 ’]
The Picture of Dorian Gray,-Oscar')
W1lde-,254,©.26,1890 ]
The Secret Garden.‘France* Hodgson']
Burnett", 331,©.».1911 ')
Brave Mew World Revisited,"Aldous Huxley",184,0.22,1958 ')
Anleal Fara,"George Orwell*,112,0.15,1945 ')
The Kite Runner, "Khaled Hosseini", 372,9.33,2M3 *|
Life of Pl,"Varai rurtel",3i9»e.39.29©i')
0 leport csv
with open(‘/content/data(1).csv‘, ‘r‘, encoding-’utf 8) at csvfile:
reader - csv.DietReader(csvfile)
• Удаляем пробели и вон-символ на аагоеовков
reader.fieldnaaes - [naee.*trlp().ref»lace('\ufeff *, ’ ) for naa# In reader.fleldnaaes)
for row in reader;
print(row)Title'], row('Author'])
•- 1984, "George Orwell",328,0.39,1949 Hone
TO Kill a Hockingblrd,‘Harper Iее",281,0.25,I960 None
The Great Gatsby,"f, Scott Fitigerald*,189,0.22,1925 More
The Catcher in the Rye,"3.0. Salinger",277,9.32»1951 More
Brave New World,"Aldous Huxley",ill,0.28,1932 None
Pride and prejudice,"Jane Austen’,432,».35,1813 Hone
The Hobbit,"J.R.R. Tolkien*,316.0.40,1937 Hone
Fahrenheit 451,-«ay Bradbury",158,0.18,1953 моле
The Alehew1st,"Paulo None
Coelho*,208,6.24,1988 Non#
The Picture of Dorian Gray,'Oscar None
Wilde*,254,9.26,1890 None
The Secret Garden,‘Frances Hodgson hone
Burnett ",331,0.» ,1911 None
Brave New world Revisited,’Aldous Huxley‘,184,©.22,1958 None
An Ik# I Fare, "George Orweir,112,9.15,1945 Hone
The Kite Runner.-Khaled Hosseini".372,0.33.2003 None
Life of Pi,-Vann Hertel-,319,B.3»,29B1 None
ieport CSV
• данные о книгах, которые собираемся записать
Табл. 6.2
Код Пояснение
Импортирование модуля CSV: import csv Импортируем модуль csv, который предостав- ляет функции и классы для работы с CSV-файла- ми. Он позволяет удобно читать и записывать данные в формате CSV
Открытие CSV-файла: with open('data (l).csv', 'r', encodingsutf-8') as csvfile: open(’data (1) .csv', ’r', encoding^utf-8') от- крывает файл с именем data (1) .csv в режиме чтения ('г').Указываем кодировку utf--, чтобы корректно обрабатывать любые специальные символы with ... as csvfile — это конструкция with, которая позволяет автоматически закрыть файл после выхода из блока, что помогает из- бежать утечек ресурсов. Открытый файл будет доступен под именем csvfile
Чтение данных с помощью DictReader: reader = csv. DictReader(csvfile) csv.DictReader (csvfile) использует DictReader, чтобы создать объект reader, который считы- вает строки из файла в форме словарей (diet). В этом случае ключами словаря будут названия столбцов (заголовки) из первой строки файла, а значениями — соответствующие данные из каждого ряда
Удаление пробелов из заголовков. # Удаляем пробелы из заголовков reader.fieldnames = [name.stripO for name in reader.fieldnames] reader, f_eldnam.es — это атрибут, который со- держит список заголовков столбцов из первой строки файла. В данном случае это необходи- мо, чтобы избежать проблем, когда в заголов • ках есть лишние пробелы. [name.stripO fcr name in reader, fieldnames] —это выражение спискового включения, которое создает новый список за головков, где для каждого заголовка убираются пробелы в начале и конце строки с помощью метода strip () Таким образом мы гарантиру- ем, что заголовки будут аккуратными и без про- белов, что облегчит доступ к ним в следующих строках кода
Итерация по строкам и вывод дан- ных: for row in reader: print(row{ ’Title'], row[’Author']) for row in reader:—эго цикл, который прохо- дит по каждой строке в файле (каждой записи), представленном в виде словаря. Для каждой строки row мы можем получить доступ к дан- ным по ключам. print (row (’Title' ], row [ ’Author' ]) выводит значения по ключам Title и Author для каждой строки row. Так мы напечатаем название книги и автора на экране
Этот код открывает CSV-файл, считывает его содержимое, удаляет лиш-
ние пробелы в заголовках, а затем выводит название и автора каждой книги
из файла. Код написан таким образом, чтобы быть устойчивым к проблемам
с пробелами в заголовках, что делает его более надежным и простым в ис-
пользовании.
Использование csv.DictReader значительно упрощает доступ к данным
в CSV-файле, особенно когда есть много столбцов. Вместо использования ин-
дексов с помощью этого класса можно обращаться к значениям столбцов по
их названиям. Это делает код более читабельным и уменьшает вероятность
ошибок, связанных с неправильным порядком индексов.
import csv
# Данные о книгах, которые мы собираемся записать
books = [
['1984', 'George Orwell', 328, 0.30, 1949],
('То Kill a Mockingbird', 'Harper Lee', 281, 0.25, 1960],
('The Great Gatsby', 'F. Scott Fitzgerald', 180, 0.22, 1925],
('The Catcher in the Rye', 'J.D. Salinger', 277, 0.32, 1951],
('Brave New World', 'Aldous Huxley', 311, C.28, 1932],
['Pride and Prejudice', 'Jane Austen', 432, 0.35, 1813],
['The Hcboit', 'J.R.R. Tolkien', 310, G.4C, 1937],
['Fahrenheit 451', 'Ray Bradbury', 158, 0.18, 1953],
['The Alchemist', 'Paulc Coelho', 208, 0.24, 1988],
('The Picture of Dorian Gray', 'Oscar Wilde', 254, 0.26, 1890],
('The Secret Garden', 'Frances Hodgscn Burnett', 331, 0.29, 1911],
('Brave New World Revisited', 'Aldous Huxley', 184, 0.22, 1958],
('Animal Farm', 'George Orwell', 112, 0.15, 1945],
('The Kite Runner', 'Khaled Hosseini', 372, 0.33, 2003],
('Life of Pi', 'Yann Martel', 319, C.30, 2001]
]
# Открытие файла для записи
with open ('output, csv', 'w', newline1*", encoding" utf-8') as csvfile:
# Создание объекта writer
writer = csv.writer(csvfiie)
# Запись заголовков в файл
writer.writerow(['Title', 'Author', 'Pages', 'Weight',
'PublishedYear'])
# Запись данных с книгах
for book in books:
writer.writerow(book) # Каждая книга - это список, который бу-
дет записан как строка
Мы видим, что слева появился файл output.csv.
ТЪв Kit* Rixinsr.'Rhbled Hosseini“,372,0.33,2003 Mon*
life of Pi,“Venn Msrtel*.319,0.30,2061 Non*
0 Inport csv
• Дамм о книгах, которые * собираемся запекать
oooks - (
(1904 , 'Georf* Orweir, М*. 6.М, 19*9),
(То Kill a Mockingbird*, ‘Harper Lee*. 281, 0.25, 19*0),
('The Great Gatsby-', *F. Scott Fitzgerald*, 1», 0.22, 1925],
(‘The Catcher In the Ry*', 3.0. Salinger'» 277, 0.32, 1951],
/Brave New World1. ‘Aldous Huxley*. 311. 0.2B, 1932).
/Pride and Prejudice’, ’Jane Austen', *32, 6.И, 1613],
('The Hobbit, *7.R.R. Tolkien'. 316. 0.40, 1937],
(’Fahrenheit 451*. ‘Ray Bradbury*, 158, 6.18, 1953),
(•The AlchMklst*. 'Paulo Coelho , 266, 0.24, 1968],
(’The Picture of Dorian Gray". ’Oscar Wilde*. 254, 6.26, 1896),
(’The secret Garden*, 'Frances Hodgson Burnett', 331, 6.29, 1911],
('Brave New world Revisited', 'Aldous Huxley', i»a, 6.22, 1998],
('Anlaal Fara*. ‘George Orwell*. 112, 0.15. 1945],
( The Kite Runner'. 'Khaled Hosseini', 372, 6.33, 2M3],
('Life of M*. 'Yam Kartel*. 319. 0.36, 2W1]
1
• Отксагтие файла для аапмсм
with open(‘output.csv', *w‘, newline-1', encoding-°utf 8*) as csvfile:
Соманме объекта writer
writer - csv,writer(csvflle)
• Запись ааголоекоа a p*An
writer.wrlterow(('Title*. 'Author', 'Pages', 'Weight*. 'PufellshedYear*})
9 Запись данных о книгах
for book in books:
wrlt*r.wrlt<row(book, * каждая книга - >то список, который будет записан «лк строка
leport «V
* Открытие файла дяя нтемкя
Рис. 6.9
Табл. 6.3
Код Пояснение
Импортирование модуля: import csv
Данные о книгах: bocks = [...] Список списков, где каждый вложен- ный список представляет книгу и со- держит ее заголовок, автора, количес- тво страниц, вес и год публикации
Открытие файла для записи with open('output.csv', ’w', newllne=", encoding='utf-t') as csvfile: Открывает файл - utput.csv для записи (V). Если он уже существует, то будет перезаписан. Указание newline='' позволяет избе- жать добавления пустых строк между записями в CSV в некоторых системах (например, Windows)
Создание объекта writer: writer = csv.writer(csvfile)
Запись заголовков writer.writerow(('Title', 'Author', 'Pages', 'Weight', 'PublishedYear']) Записывает первую строку с заголов- ками
Запись данных о книгах. for Dock in books: writer.writerow(bock) 1 Каждая книга - это список, который будет записан как строка Цикл проходит по каждой книге в списке books и записываегее данные в файл
Этот код создаст файл output. csv, который будет содержать данные о кни-
гах в формате .csv, включая заголовки. Вы можете дополнительно изменять
данные в списке bocks, если необходимо.
После записи данных в файл output.csv мы можем открыть его и прочи-
тать содержимое, чтобы убедиться, что все записано корректно.
Ниже приведен код, который открывает созданный CSV-файл и выводит
содержимое на экран:
import csv
ff Открытие файла для чтения
with open('output.csv', 'r', encoding^ utf-8') as csvfile:
reader = csv.reader(csvfiie)
# Чтение и вывод содержимого файла
for row in reader:
print(row) # Каждая строка будет выведена как список значений
Q import cs\|
t Открытие файла для чтения
with орел(‘output.csv', 'г*, encoding-“utf-8') as csvfiler
reader - csv.reader(csvfile)
w чтение и вывод содержимого файла
for row in reader
print(row) « Каждая строка будет выведена как список значений
— (‘Title’, 'Author', ’Pages’, 'Weight', 'PvblBhedYear*)
['1984', 'George Orwell', '328', '0.3', '1949']
['To Kill a Mockingbird'Harper Lee', '281', '0.25', 'I960']
('The Great Gatsby’, ’F. Scott Fitzgerald*, '180', '0.22', ’1925']
['The Catcher in the Rye’, ’1.0. Salinger', ’277', ‘0.32’, ‘1951'j
('Brave Mew world', 'Aldous Huxley', '311', ’0.28’, 1932')
('Pride and Prejudice', 'lane Austen', '432', '8.35', ‘1813’)
['The Hobbit', ‘l.R.R. Tolkien', '310', ’0.4‘, '1937')
('Fahrenheit 451', 'Ray Bradbury', '158', '0.18', '1953')
('The Alcheeist', 'Paulo Coelho', 208', '0.24', ’1988’]
['The Picture of Dorian Gray', 'Oscar Wilde9, '2S4‘, '0.26', '1890']
['The Secret Garden', 'Frances Hodgson Burnett', '331', '8.29', '1911*J
['Brave New world Revisited*, ‘Aldous Huxley’, '184’, ‘0.22’, '1958']
('Aniaal Fare', 'George Orwell’, '112', ’0.15’, '1945’J
['The Kite Runner', ‘Khaled Hosseini', '372', *0.33*, '2003')
('Life of Pl”, Yann Martel’, ’319', e.3‘, 2001)
ieport json
t Оригинальные данные о мекмленмых книгах
books - [
{
"Title”: "The whispering Shadows",
’Author": "Luna Starfall’,
“Pages’: 358,
’PublishedYear": 2022
}.
{
Рис. 6.10
Сначала записываем данные в файл, а затем с помощью второго фрагмен-
та кода открываем и читаем файл, проверяя, что данные записаны правиль-
но. Запустив оба куска кода один за другим, мы получим доступ к созданному
CSV файлу и увидим все его содержимое на экране.
Табл. 6.4
Код Пояснение
Импортирование модуля: import csv Импортируем модуль csv, который понадо- бится для чтения и работы с CSV-файлами
Открытие файла для чтения: with open('output.csv', 'г', encoding^utf-8') as csvfile: Открываем файл output.csv в режиме чтения ('г')
Создание объекта > eader: reader = csv.reader(csvfile) Создаем объект reader, который будет считывать строки из CSV-файла
Чтение и вывод содержимого файла for row in reader: print(row) 5 Каждая строка будет выве- дена как список значении Обходим каждую строку п файле и вы- водим ее на экран. Каждая строка будет представлена как список значений, разде- ленных запятыми
Чтение и запись данных в формате JSON
JSON — это легковесный формат обмена данными, который легко читать
и писать человеку, а также легко парсить и генерировать машине. JSON ос-
нован на текстовых данных и используется для представления структуриро-
ванной информации.
Общая структура JSON-файда
В общем виде структура JSON-файла может быть представлена следую-
щими элементами:
"keyl": valuel,
"key2": value2,
"кеуЗ": {
"nestedKeyl": nestedValuel,
"nesteaKey2": r.estedValue2
},
"key4": [
valueA,
valueB,
"innerKey": innerValue
],
"key5": true, // логическое значение
"кеуб": null // значение null
Объяснение:
1. Корневой объект: JSON-фай,л начинается с фигурных скобок {), что
обозначает, что это объект.
2. Ключи являются строками и должны быть заключены в двойные кавыч-
ки Значения могут быть одного из следующих типов:
• строка, заключенная в двойные кавычки "string";
* число, например 42 или 3,14;
• логическое значение true или false;
• значение null;
• вложенный объект, также заключенный в фигурные скобки {};
• массив, заключенный в квадратные скобки [], который может содер-
жать значения различных типов.
3. Вложенные объекты могут содержать свои собственные ключи и значе-
ния, обеспечивая многомерное представление данных.
4. Массивы могут содержать списки значений, включающие строки, числа,
логические значения, null, объекты и другие массивы.
Создание JSON-файла с помощью Pvthon
Модуль json предназначен для работы с данными, представленными
в формате .json, который является стандартом для обмена данными между
веб-приложениями.
Алгоритм создания решения
1. Определение данных. Создайте структуру данных (в данном случае —
словарь), который будет содержать информацию, которую вы хотите запи-
сать в JSON-файл.
2. Открытие файла. Используйте конструкцию with open () для открытия
файла (или создания, если он не существует) в режиме записи. Это гаранти-
рует, что впоследствии файл будет правильно закрыт.
3. Запись данных. Используйте json.dump() для сериализации объекта
Python (в данном случае словаря) и записи его в файл в формате json. Опция
для форматирования помогает сделать вывод как можно более понятным.
import json
# Оригинальные данные о вымышленных книгах
books = [
"Tide": "The Whispering Shadows",
"Author": "Luna Starfall",
"Pages": 350,
"PublishedYear": 2022
},
{
"Title": "A Journey Through Time",
"Author": "Oliver Bright",
"Pages": 420,
"PublishedYear": 2021
},
"Title": "The Last Enchanter",
"Author": "Ivy Green",
"Pages": 275,
"PublishedYear": 2023
{
"Title": "Beneath the Silver Sky",
"Author": "Maxwell Rivers",
"Pages": 310,
"PublishedYear": 2020
},
{
"Title": "Echoes of the Forgotten",
"Author": "Sophia Dreamweaver",
"Pages": 290,
"PublishedYear": 2019
]
# Запись данных в JSON файл
with open('original_bccks.json', 'w', encoding^ utf-8') as jscnfile:
json.dump(books, jsonfile, ensure ascii=False, inaent=4)
print("<t»aiin 'original_books.json' создан.")
Q iupc**t jto*'
book* (
(
•TRI*’: "Th< WM«p«ring Sh*dow»',
’Author”: “Счал $t»rf*ll*,
’P*ge»“: ISO,
-PublishedYear’: 2022
b
<
“Title’s “A Journey Through T£ee“,
“Author”1 “Oliver Bright*»
“Pages": 420,
“PublishedYear-; 2021
Ъ
<
"Title”: “The Lest £n<heoter“,
’Author’: “ivy Greer",
“Pages"; 275,
“PublUhedYeer": 2M3
<
’Title’s "beneath the Silver Sky’,
"Author": “Harwell 0iver-*“,
“Pages’: 310,
“PublishedYear’: 2029
Ъ
<
"Title’s "fcboe* of the Forgotten’,
"Author"! “Sophia DreaMeaver",
' Page: ! 2«,
“PublishedYear-: 2010
}
1
• Затее дан««м • ISON файл
with openoriginal_book*,json’, •«', encoding»'utf-4') as jsonfilei
jsoei.duap( books, jsonfile, *n*ure_a*<ii»Fal*e, lrdent*4)
prir»t(’ea4n 'orLglnal_books.json' создан..’)
аайг ’original-books,json <oiM".
Рис. 6.11
Давайте подробно рассмотрим, как в приведенном коде происходит со-
здание и запись вымышленных данных о книгах в JSON-файл с использова-
нием модуля json в Python.
Табл. 6.5
Код Пояснение
Импортирование модуля- import json Импортируем стандартный модуль json, который предоставляет функции для ра- боты с JSON-данными. Модуль позволяет легко преобразовывать Python-объекты (например, списки и словари) в формат .json и наоборот
Подготовка данных: books = [ ( "Title": "The Whispering Shadows", "Author": "Luna Starfall", "Pages": 350, "PublishedYear": 2022 1, ( "Title": "A Journey Through Time", "Author": "Oliver Bright", "Pages": 420, "PublishedYear": 2021 }, Создаем список books, который содержит несколько словарей. Каждый из них пред- ставляет собой объект книги с четырьмя ключами. "Title": название книги. "Author" имя автора. "Pages": количество страниц в книге. "PublishedYear": год публикации книги Эти данные представляют вымышленные книги и содержатся ь формате, который легко может быть преобразован в JSON
Код Пояснение
"Title": "The Last Enchanter", "Author": "Ivy Green", "Pages": 275, "FutlishedYear": 2023 ), ( "Title": "Beneath the Silver Sky", "Author": "Maxwell Rivers", "Pages": 31C, "PublishedYear": 2020 }, ( "Title": "Echoes of the Forgotten", "Author": "Sophia Sreamweaver", "Pages": 29C, "FutlishedYear": 2019 } ]
Запись данных в JSON-файл: with open('originalbooks.json', 'w', er.coding='utf-8') as jsonfile: jsen.dump(books, jsonfile, ensure^ ascii=False, lndent-4) Открытие файла для записи- open (’originaibooks.json', V, encoding^utf-8'):. Открывает (или со- здает) файл с именем original books. json в режиме записи ('w'). Параметр encodings utf-E' гарантирует, что файл будет записан с использованием кодировки UTF-8. что позволяет коррек- тно сохранять и отображать символы из различных языкок Запись данных: json.dump (books, jsonfile, ensure ascii=False, indent=4). С помощью функции json.dump() записы- ваем список books в открытый JSON-файл (jsonfile). ensure ascii=False. Это позволяет сохра- нять не ASCII-символы (например, ки- риллицу или специальные символы) в их исходной форме, чтс южно для обеспече- ния корректного отображения текста. indent-4. Форматирует JSON с отступами, что улучшает читаемость файла, делая его более структурированным и понятным
Завершение и уведомление: print("Файл 'original_books.json' со- здан.") Эта строка выводит на экран сообще- ние о том, что файл original_bcoks.json успешно создан. Так мы убедимся, что все прошло успешно
Код обеспечивает создание структуры данных о вымышленных книгах,
а затем записывает их в легко читаемый формат JSON. Модуль json делает
процесс преобразования и записи данных простым и эффективным.
Чтение данных из JSON-файла
Для чтения данных из существующего JSON-файла в Python также исполь-
зуется модуль json. Ниже приведен пример кода, который открывает файл
original_books. json, читает его содержимое и выводит данные на экран.
Код для чтения из JSON-файла: import json
import json
# Открытие файла для чтения
with open('original_books.json', 'r', encodingsutf-8') as jsonfile:
# Чтение данных из JSON файла
books = json.load(jsonfile)
ff Вывод данных на экран
for book in books:
print(f'Title; (book['Title']}, Author: (book['Author'j), Pages:
{bock['Pages']}, PublishedYear: {bookJ'PublishedYear']}")
with open("originalbooks.json’, ‘w’, encoding» utf 8’) as jsonfile:
json.dump(books, jsonfile, ensure_ascii-False, indents)
print("Файл ’original_books.json* * создан.")
Файл ’originaI books.json' создам.
------------------------------------------------------------------------------------------------------------------- Ф Ф У 0
ф import json
• Открытие файла для чтения
with open('original books.json*, 'r', encoding-’utf’8') as jsonfile:
« 'Пение данных из JSOH файла
books - json.load(jsonfile)
• Вывод данных на экран
for book in books:
print(f"Title: ‘bookj‘Title*]}, Author: (book('Author']}, Pages: {book[’Pages’)}, PublishedYear: {book[’PublishedYear’)}")
— Title: The whispering shadows. Author: tuna Starfall, Pages: 359, Published Year: 2022
Title: A Journey Through Time, Author: Oliver Bright, Pages: 420, Published Year: 2821
Title: The last Enchanter, Author: ivy Green, Pages: 275, Published Year: 2023
Title: Beneath the Silver Sky, Author: Maxwell Rivers, Pages: 310, Published Year: 2020
Title: Echoes of the Forgotten, Author: Sophia Dreamweaver, Pages: 290, Published Year: 2019
import xml.etree.ElementTree as ET
• Создание корневого элемента «library»
library ET.Eleeent("library”)
9 Список книг с их данными
Рис. 6.12
Объяснение:
Табл. 6.6
Код Пояснение
Импортирование модуля: import json Импортируем модуль json, который позволяет работать с форматами JSON
Открытие файла для чтения- with орел(*original_books.json', 'г', enccding='utf-8') as jsonfile: Открываем файл original books. j son в режиме чтения ('г') с кодировкой UTF-8
Чтение данных из JSON файла: books = json.load(jsonfile) Функция json.load(jsonfile) считыва- ет данные из открытого JSON-файла и преобразует их обратно в структуру данных Python (в нашем случае — список словарей)
Вывод данных на экран: for book in books: print(f"Title: {book{'Title']}, Author: {book{'Author')], Pages: {bock['Pages']), Published Year: {book[’PublishedYear')}") Перебираем список Ьоскэ и для каж- дого объекта книги выводим инфор- мацию о названии, азторе, количестве страниц и годе публикации
Запустив этот код, мы можем считать и увидеть все вымышленные книги,
которые сохранены в файле origir.al tooks. json. Этот процесс демонстриру-
ет, как работать с данными в формате JSON в Python с использованием мо-
дуля j son.
Работа с XML-документами
XML — это расширяемый язык разметки, который используется для хране-
ния и передачи данных. Он предоставляет способ описания структуры и со-
держания данных с использованием человекочитаемых тегов. Язык широко
применяется в различных областях — веб-разработке, обмене данными меж-
ду системами, конфигурационных файлах и др., где необходимо хранение
структурированной информации.
Общий вид структуры XA1L-документа:
<?xml. version®" 1.0" encoding="UTF-8"?>
<root>
<elementl attributel="valuer' attribute2="value2">Content of
elementl</elementl>
<element2>
<subelementl>Content of subelenientl</subelenentl>
<subelement2>Ccntent cf subelement2</subelement2>
</element2>
<element3>
esubelement3 attribute="value">Content cf subelement3e/
subeleirer:t3>
e/element3>
e/root>
Объяснение:
1. Заявление XML. e?xml version="1.0" encoding="UTF-8"?> — это стро-
ка, указывающая, что перед нами ХМL-документ, а также его версию и коди-
ровку.
2. Корневой элемент eroot> содержит все остальные элементы. Каждый
XML-документ должен иметь только один корневой элемент.
3. <elementl>, eelement2>, eelement3> — это элементы XML. Они могут со-
держать текст, другие элементы или и то и другое.
4. Атрибуты attributel-"valuel" предоставляют дополнительные харак-
теристики для элементов. Они определяются в открывающем теге элемента.
5. Элементы могут содержать вложенные элементы (например,
esubelementl> и esubelement2> внутри <eleraent2>), что позволяет создавать
иерархическую структуру данных.
Пример XML-документа, который описывает книги:
<?xml version="1.0" encoding="UTF-8"?>
<library>
<book title="The Whispering Shadows" author="Luna Starfall"
publishedYear="2022">
<pages>350<7pages>
</Ьоок>
ebook title="A Journey Through Tine" author="Oliver Bright"
publishedYear="202r,>
<pages>429</pages>
</book>
ebook title="The Last Enchanter" author="Ivy Green"
publishedYear="2023">
epages>275e/pages>
e/book>
e/library;*
Создание XML-файла на Python
Для работы с XML-файлами используется модуль xml .etree.ElementTree,
предоставляющий инструменты для парсинга и создания XML-документов.
Давайте разберем, как создается XML-файл с данными о вымышленных
книгах на основе предоставленного кода, по шагам, объясняя каждую опера-
цию и то, как это обычно делается в Python.
Объяснение:
1. Импортирование модуля: import xml.etree.ElementTree as ET.
Импортируем модуль ElementTree, который является частью стандартной
библиотеки Python и предоставляет удобный интерфейс для создания и ма-
нипулирования XML-документами. Это важно, так как без импорта мы не
сможем использовать функции этого модуля.
2. Создание корневого элемента: library = ET.Element("library").
Создаем корневой элемент XML с именем <library>. Он будет служить
контейнером для всех книг, которые мы планируем добавить. Корневой эле-
мент нужен, так как в XML-документе может быть только один корневой
объект.
3. Определение списка книг:
books = [
{"title": "The Whispering Shadows", "author": "Luna Starfall",
"PublishedYear": "2022", "pages": 350),
{"title": "A Journey Through Time", "author": "Oliver Bright",
"PublishedYear": "2021", "pages": 420},
{"title": "The Last Enchanter", "author": "Ivy Green",
"publishedYear": "2023", "pages": 275},
{"title": "Beneath the Silver Sky", "author": "Maxwell
Rivers", "publishedYear": "2020", "pages": 310},
("title": "Echoes of the Forgotten", "author": "Sophia
Dreamweaver", "publishedYear": "2019", "pages": 290}
Определяем список словарей, где каждый содержит информацию о книге
(название, автор, год публикации и количество страниц). Это удобно, так как
позволяет легко добавлять и обрабатывать данные о книгах.
4. Цикл для добавления книг в библиотеку:
for bock_data in books:
book = ET.SubElement(library, "bock", title=book_
data{"title"], author=book data["author"], publishedYear=book_
data("publishedYear"1)
pages = ET.SubElement(book, "pages")
pages.text = str(book_daca["pages"])
Проходим по каждому элементу из списка books:
• ET.SubElement (...) создает новый элемент <book> под корневым эле-
ментом <library>, добавляя атрибуты для названия, автора и года пуб-
ликации.
• Для каждой книги добавляем элемент cpages>, который содержит текс-
товое значение, равное количеству страниц в книге.
• Используем метод ET.SubElement, который рендерит необходимые вло-
женные структуры XML.
5. Создание XML-дерева и запись в файл:
tree = ET.ElementTree(library)
tree.write("books.xml”, encoding="utf-8", xml_declaration=True)
Создаем ElementTree из корневого элемента library. Это позволяет соб-
рать все элементы и готовить их для записи. Вызов метода write произво-
дит запись дерева в файл books.xml. Указываем кодировку (encoding="utf-8")
и добавляем строку декларации XML (xml_aeclaration=True), чтобы файл со-
держал идентификатор версии и кодировки.
6. Вывод сообщения о создании файла: print ("Файл 'bocks. xml' создан.").
Эта строка выводит в консоль уведомление о том, что файл был успешно со-
здан. Так мы получаем подтверждение, что все прошло успешно.
Таким образом, в этом процессе мы создаем XML-докумснт от начала до
конца, используя библиотеку xml.ecree.ElementTree. Каждый шаг аккуратно
организует данные о киш ах, структурируя их в формате XML, чго позволяет
эффективно сохранять и передавать информацию. Это типичный подход для
работы с XML в Python.
import xml.etree.ElementIгее as ET
# Создание корневого элемента <library>
library = ET.Element("library")
if Список книг с их данными
bcoks = [
{"title": "The Whispering Shadows", "author": "Luna Starfall",
"publishedYear": "2022", "pages": 350},
{"title": "A Journey Through Time", "author": "Oliver Bright",
"publishedYear": "2021", "pages": 420),
{"title": "The Last Enchanter", "author": "Ivy Green",
"publishedYear": "2023", "pages": 275},
{"title": "Beneath the Silver Sky", "author": "Maxwell Rivers",
"publishedYear": "2020", "pages": 310},
{"title": "Echoes of the Forgotten", "author": "Sophia
Dreamweaver", "publishedYear": "2019", "pages": 290}
# Добавление каждой книги в библиотеку
for book data in books:
bcok = ET.SubElement(library, "book", title=book_data["title"],
author=book_data("author"], publishedYear=book data("publishedYear"])
pages = ET.SubElement(book, "pages")
pages.text = str(book data["pages"))
f Создание дерева и запись его в файл
tree = ET.Eleir.er.tTree (library)
tree.write("bcoks.xml", encoding-"utf-8", xml_declaration=True)
print("Файл 'books.xml' создан.")
f----------------------------------------------------------------------------------------------------------------------- Ф Ф ? : —
Q iwport xwl.etree.ElewentTree as ET
• Создание корневого элемента <library>
library • ET.Elewent("library“)
i Список книг с их даншни
books - [
{"title": "The Whispering Shadows", "author": "Luna Starfall", "publishedYear": "2022", "pages": 35©},
("title": "A Tourney Through Time", "author": "Oliver Bright", "publishedYear": "2021", "pages": 42©},
{"title": “The Last Enchanter", "author": "Evy Green", "publishedYear": "2023", "pages”: 275},
("title": "Beneath the Silver Sky", "author": "Maxwell Rivers", "publishedYear": "2020", "pages": 310),
("title": "Echoes of the Forgotten", "author”: "Sophia Dreamweaver”, "publishedYear": "2019", "pages": 290)
]
* добавление каждой книги в библиотеку
for book_data in books:
book ET. SubEi ewent (library, "book", title«book_dataf“title"], author«book_datd[“author"], pub!ishedYear«book_data["publishedYear
pages ET.Subtlcwentfbook, "pages")
pages.text • str(book_data|"pages"])
• создание дерева и запись его е файл
tree ET.ElementTree(library)
tree.write("books, xml", encoding®"utf-8", xnl_declaration>True)
print("oaRn ’books.»!" создан.")
••• Файл ’books.»!* создан.
Рис. 6.13
Табл. 6.7
Код Пояснение
Импортирование библиотеки: import xml.etree.ElementTree as ET Импортируем модуль ElementTree из библиотеки xml. etree. Это основной модуль для работы с XML в Python
Создание корневого элемента: library = ET.Element("library") Создаем корневой элемент <library>, который будет содержать все книги
Создание списка книг: books = [...] Определяем список словарей, где каждый словарь представляет книгу, содержащую название, автора, год публикации и количество страниц
Добавление книг в библиотеку: for book_data in books: book = ET.SubElement(library, "book", title=bcok_data["title"], author=bock_ data("author"], publishedYear=book_ data["publishedYear"]) pages = ET.SubElement(book, "pages") pages.text = str(book_data["pages"]) Проходим по каждой книге и создаем элемент <book>, добавляя атрибуты title, author и publishedYear. Затем создаем элемент <pages> и задаем его текст
Код Пояснение
Создание дерева и запись в файл: tree = ET.ElementTree(library) tree.write("books.xml", encoding="utf-8", xml_declaration=True) Создаем дерево XMi из корневого элемента library и записываем его в файл bocks.xml, настраивая кодиров- ку и добавляя строку декларации XML
Вывод сообщения: print("Файл 'books.xml' создан.") Уведомление о том, что файл был успешно создан
Этот код создает XML-файл под названием books.xml, который будет со-
держать данные о вымышленных книгах в указанном формате. XML-файл
структурированно отображает информацию о каждой книге. Вы можете от-
крыть его с помощью текстового редактора, чтобы увидеть содержимое.
Ч гение и анализ XML-файда
Для чтения и анализа XML-файла в Python можно использовать модуль
xml.etree.ElementTree. Он позволяет загружать XML-документы, извлекать
их элементы и атрибуты, а также работать с данными внутри этих докумен-
тов. Давайте рассмотрим, как прочитать созданный ранее файл books.xml
и проанализировать его содержимое.
Файл ' books. хл>1' создан.
ф import xml.ntree.ElementTree as Ет|
» Окрываем xml файл и ларсич его
tree = EI.parse(‘books.xml’)
rout tree.getroot() # Получаем корневой элемент
4 аывод информации о каждой книге
for book in root.findallf'book'):
title = book.get!'title') » Получаем атрибут title
author - book.get('author') 4 Получаем атрибут author
publishedyear = book.get('publishedYear') # Получаем атрибут publishedYear
pages = book.find('pages').text # Получаем текстовое содержимое элемента <pages>
print(f"Title: (title). Author: (author), Year: (publishea.jrearj, Pages: {pages}")
— Title: The Whispering shadows, Author: Luna startali. Year: 2022, Pages: 350
Title: A Journey Through Time, Author: Oliver Bright, Year: 2021, Pages: 420
Title: The Last Enchanter, Author: Ivy Green, Year: 2023, Pages: 275
Title: Beneath the Silver Sky, Author: Maxwell Rivers, Year: 2020, Pages: J10
Title: Echoes of the Forgotten, Author: Sophia Dreamweaver, Year: 2019, Pages: 290
I pip install Pillow matplotlib
from P1L import image
import matplotlib.pyplot as pit
# Открытие изображения
image_path = '/content/Pic.jpg' » путь к изображению
Пример кода для чтения и анализа XML-файла:
import xml.etree.ElementTree as ET
# Открываем XML файл и парсим ere
tree = ET.parse('books.xml')
root = tree.get root() # Получаем корневой элемент
# Вывод информации о каждой книге
for book in rcot.findall('book'):
title = book.get('title') # Получаем атрибут title
author = bock.get('author') # Получаем атрибут author
published_year = book.get. ('publishedYear') f Получаем атрибут
publishedYear
pages = book.find('pages').text # Получаем текстовое содержимое
элемента <paqes>
print(f'Title: {title), Author: (author), Year: (published year},
Pages: {pages}")
Табл. 6.8
Код Пояснение
Импортирование модуля: import xml.etree.ElementTree as ET Начинаем с импорта библиотеки ElementTree, которая используется для работы с XML
Парсинг XML файла: tree = ET.parse!'books.xml') Используем функциюET.parsed для загруз- ки и парсинга содержимого файла books. xml. Это создает дерево элементов, пред- ставляющее содержимое XML-документа
Получение корневого элемента; root = tiee.getroctd Извлекаем корневой элемент XML-доку- мента с помощью метода getroot (), что даст нам доступ ко вложенным элементам
Итерация по элементам <book>: for book in root.findall('bock'): Используем findall ('book'), чтобы полу- чить все элементы <Ьоск>, находящиеся под корневым элементом. Теперь мы можем перебрать каждую книгу и извлечь нужные данные
Извлечение данных о книге: title = bock.get('title') i Получаем атрибут title author = book.get('author') f Получа- ем атрибут author published_year = book. get('publishedYear') ? Получаем атри- бут publishedYear pages = bock.find('pages').text » Получаем текстовое содержимое элемента <pages> Используем метод get () для получе- ния значений атрибутов title, author и publishedYear. Для элемента <pages> используем find( 'pages'), чтобы получить его эле- мент, а затем считываем текст, который он содержит
Код Пояснение
Вывод информации на экран: print(f'Title: {title}, Author: {author}, Year: {published_year}, Pages: (pages)") После извлечения всех необходимых дан- ных выводим их на экран в удобочитаемом формате
Запустив этот код, мы можем считать данные из файла books.xml и вывес-
ти информацию о каждой содержащейся в нем книге.
Такой подход позволяет легко анализировать структуры XML и извлекать
данные, что делает его полезным инструментом для работы с ХМ L-докумен-
тами в Python.
Обработка медиафайлов
Работа с изображениями
Python предлагает множество библиотек для работы с изображениями, и один
из самых популярных инструментов — это библиотека PIL (Pxthon Imaging
Library) |84], которая теперь реализована в модуле Pillow. Также существует
несколько других библиотек, таких как OpenCV, Matplotlib и Scikit-iinage, ко-
торые могут быть использованы в зависимости от ваших нужд.
Давайте рассмотрим основные возможности работы с изображениями
в Python на конкретных примерах кода с использованием библиотеки Pillow
и Matplotlib.
Изменение размера изображения
Для начала загрузим изображение
:= Файлы
в В 13
*.
о
* № '!e_aata
|j Pic.jpg
□ d books.xml
g| data (1).csv
or>ginal_bookS;Son
output.csv
Рис. 6.16
Установка необходимых библиотек
Работая в Google Colab, сначала нужно установить библиотеку Pillow. Вво-
дим в ячейку Colab:
!pip install Pillow matplotlib
Title: The Whispering Shadows, Author: Luna Starfall, Year: 2022, Pages: 350
Title: A Journey Through Tine, Author: Oliver ©right. Year: 2021, Pages: 4M
Title: The Last Enchanter, Author: Ivy Green, Year: 2023, Pages: 275
Title: Beneath the Silver Sky, Author: Maxwell Rivers, Year: 2020, Pages: 310
Title: Echoes of the Forgotten, Author: Sophia Oreamweaver, Year: 2019, Pages: 290
, Ф Ф V 0 : —s
Q Ipip install Pillow natplcjtlib
Requirement already satisfied: Pillow in /usr/local/lib/python3.12/dist-packages (11.3.0)
Requirement already satisfied: matplotlib in /usr/Iocal/lib/pytho<>3.12/dist°package$ (З.10.0)
Requirement already satisfied: contourpy>»i,0.1 in /u$r/local/lib/python3.i2/di$t-package$ (from matplotlib) (1.3.3)
Requirement already satisfied: cycler>-0.10 in /usr/local/lib/python3.12/dist-packages (from matplotlib) (0.12.1)
Requirement already satisfied: font tool s>* *-4.22.0 in /usr/local/lib/python3.12/dist packages (from matplotlib) (4.61.1)
Requirement already satisfied: kiwisolver>-1.3.1 in /usr/local/lib/python3.12/dist packages (from matplotlib) (1.4.9)
Requirement already satisfied: numpy>-1.23 in /usr/local/lib/pythonj.12/dist-packages (from matplotlib) (2.9.2)
Requirement already satisfied: packaging>»2©.0 in /usr/local/lib/python3.12/dist*packages (from matplotlib) (25.©)
Requirement already satisfied: pyparsing>-2.3.1 in /u$r/local/lib/python3.12/dist-packages (from matplotlib) (3.3.1)
Requirement already satisfied: python datevtil>-2.7 in /usr/local/lib/python3.12/dist-packages (from matplotlib) (2.9.0.post©)
Requirement already satisfied: six>-1.5 in /usr/local/lib/python3.12/dist-packages (from python-dateutil>«2.7->matplotlib) (1.17.0)
from PIL import Image
import matplotlib.pyplot as pit
а Открытие изображения
image_path */content/Pic.jpg * » путь к изображению
image Image.open(image_path)
plt.shcwQ
• Показ изображения
pit.imshcw(image)
Рис. 6.17
1. Импортирование необходимых библиотек:
from PIL import Image
import matplotlib.pyplot as pit
Ipip install Pillow matplotlib
Requirement already satisfied: Pillow in /u$r/local/lib/python3.12/di$t packages (11.3.a)
Requirement already satisfied: matplotlib in /usr/locaL/lib/python3,12/dist-packages (3.10.O)
Requirement already satisfied: contourpy>-l.0.1 in /usr/local/lib/python3.12/dist-package$ (from matplotlib) (1.3.3)
Requirement already satisfied: cycler>»e.i0 in /usr/local/lib/python3.12/dist packages (from matplotlib) (0.12.1)
Requirement already satisfied: fonttools>-4.220 in /usr/local/lib/python3.12/dist packages (from matplotlib) (4.61.1)
Requirement already satisfied: kiwisolver>»l.3.1 in /usr/local/lib/python3.12/dist-packages (from matplotlib) (1.4.9)
Requirement already satisfied: numpy>-1.23 in /usr/local/lib/python3.12/dist-packages (from matplotlib) (2.0.2)
Requirement already satisfied: packaging>-20.0 in /usr/local/Mb/pytlwi3.12/dist-packages (from matplotlib) (25.0)
Requirement already satisfied: pyparsing>-2.3.1 in /usr/local/Iib/python3.i2/dist-packages (from matplotlib) (3.3.1)
Requirement already satisfied: pyttxxi-datevtil>-2.7 in /usr/local/lib/pytbon3.12/dist-packages (from matplotlib) (2.9.0.post©)
Requirement already satisfied: six>«1.5 in /usr/local/lib/python3.12/dist packages (from python-dateutil>«2.7->matplotlib) (1.17.0)
------------------------------------------------------------------------------------------------------------------- Ф Ф V S ; -
0 from PIL import Image]
import matplotlib.pyplot as pit
from PIL import Image
import matplotlib.pyplot as pit
» Открытие изображения
image_path '/content/Pic.jpg‘ w путь к изображении
image I mage.open(image.path)
plt.$how()
• Показ изображения
pit. imshow nmage)
pit.axis(‘off') * * Отклимаем оси
Рис. 6.18
2. Открытие изображения:
from PIL import Image
import matplotlib.pyplot as pit
if Открытие изображения
rmage_pat.h = '/content/Pic.jpg' I путь к изображению
image = Image.open(image_path)
plt.showO
if Показ изображения
plt.imshow(image)
pit.axis('off') # Отключаем оси
plt.showO
0 free Pit import I«t< |
iaport lib.pyplot «> pit
• Открути* *»o6p*«w«"
l**C*_p*th • */content/Pic jpg‘ f путь * и»о6р*ж*нм«
i«e<*
plt.sbow()
» Лок«» и»оОр«>*имя
pit. ie»bo*K i*U<)
plt.*xi»('off") • Откмчмм оси
plt.show()
Рис. 6.19
3. Основные операции с изображениями:
# Изменение размера изображения
♦ Изменение размера
new size = (20J, 200) # Новый размер
resized image = image.resize(new size)
# Показ измененного изображения
pit. imshow(resized image)
plt.axis('off')
pit.show()
• H1MHHIWI* р*Ж*р4
n*w_iiz* (290, 209) • Мовь^ p*»wp
• Пока» О м>рбр*пмия
pit. iash<M<r*siz*diN(«)
plt.«xi»('off")
pit. «NowOj
• Обратка иаобрааоания (loft, tippar, rigfit, lower)
cropped.»»** • imp*, crop ((SO, 5Й, ЭОО, SOO))
Обрезка:
# Обрезка изображения (left, upper, right, lower)
cropped-image = image.crop((50, 50, 300, 300))
# Показ обрезанного изображения
pit.imshow(cropped_image)
pit.axis('off')
pit.show()
О юреха июбр«ния (left, upper, right, lower)
cropped. Uage - U*<e.crop(($®, SO, Э«, Эве))
* Лсжаа обретенного изображения
pit. imhow ccopped,ieage)
plt.sxi*('off")
pit. ih©w )
• Поворот изображения не 4$ градусов
roteted_i**s* • i*»te.rotete(45)
Рис. 6.21
Поворот:
# Поворот изображения на 45 градусов
rctated_image = image.rotate(45)
> Показ повернутого изображения
pit.imshow(гotatea_image)
pit.axis('off')
pit.show()
Q поворот и>оОр«>«м»я и« лэ градусов
rotated-leaf» • 1ы|«.rotated4S)
о Пгнгая ослариутлгл изображен*
pit. ie*how(rotat*d_l*ag«)
plt.axlc(*off *)j
pit.tNow{)
Ф Ф Z В 1
Рис. 6.22
Применение фильтров:
from PIL import ImageFilter
# Применение размытия
blurred image = image.filter(ImageFilter.BLUR)
# Показ размытого изображения
pit.imsnow(blurred image)
plt.axis('off')
pit.show ()
Q roa PIL import lMf«F iit*r
• npiowiiMO рлвммтм
blared. - imc«. fl It ar(taagaf liter. BLUR)
V Dui»j |мшчы>ш и ••uflpaiunwiH
pit. iashowl Ыиг/чИ_ !-<•)
pit.axis('off*)
pit.tbwO
Г Ф У в i
ro^ized.iwto. i»v«( * ro»iz«4_ioac«. jpg *)
Рис. 6.23
4. Сохранение:
# Сохранение измененного изображения
resized_image.save('resized image.jpg')
г**1те4_Ы»<е. sove(' r«ii*4_ie»*<e =.}₽<")
* Коммрт«чил Друго* формат
• Импортируем меоФхюдим* бмФмютекм
free Ml import
i^xwt Mtplot lib.pyplot as pit
• Открыт** мкбратммя
inag*_p«th ‘/content/Pic jpf' • Путы к «юорт»*
• Испс*ыуем блок try-except для обработки смибок
try:
laege lM«t*.op«n(ia»se_patb; • Открыеми нк6р*в«мм«
print(f"ИеоЪржяе^мие ‘{ia*ge_path}* ус плато открыто.")
except FilettotroundError;
print(Ка*йл '{ ie*ge^path}‘ не найдем. Проеер^те правильность путл.’)
•xe«pt Exception о» е:
print (f-Проныюлл Оаыбка: {•)")
Рис. 6.24
5. Конвертация между форматами:
4 Конвертация в другой формат
# Импортируем необходимые библиотеки
from PIL import Image
import matplotlib.pyplot as pit
# Открытие изображения
image_path = '/content/Pic.jpg' If Путь к изображение
* Используем блок try-except для обработки сшибок
try:
image = Image.open(image_path) И Открываем изображение
print(f"Изображение '{imagejpath}' успешно открыто.")
except FileNotFoundError:
print(f"Файл '{image_path}' не найден. Проверьте правильность пути.")
except Exception as e:
print(f"Произошла ошибка: {e}")
f Конвертация в другой формат (в PNG)
pr.g_irr.age = image.convert ('RGB') fr Конвертация в RGB
png_image.save('image.png') * * Сохранение как PNG
print("Изображение успешн: сконвертировано и сохранено как 'linage.png'.")
ff Показ оригинального и конвертированного изображений рядом
fig, axes = pit.subplots(i, 2, figsize=(12, 6)) # Создаем 1 ряд и 2 колонки
# Отображаем оригинальное изображение
axes[0] .imshow(image) if Отображаем изображение
axes [0] .axis ('off') if Отключаем сси
axes(?J.set_title("Оригинальное Изображение")
# Отображаем конвертированное изображение
axes[1].imshow(png_image) # Отображаем конвертированное изображение
axes'll] .axis ('off') if Отключаем оси
axes[)].set_title("Конвертированное Изображение (PNG)")
plt.tight_layout() i Обеспечиваем равномерное распределение подграфикэв
pit.show() if Показать изображения Заключение
(Q в Конвертация в другой формат
V Импортируем необходима библиотеки
from PIl Import Image
Import matplotlib.pyplot as pit
9 Открытие изображения
lmage_path • ‘/cootent/Pic.jpg' w Путь к изображению
9 Используем блок try*except для обработки сшибок
try:
image - Image.open(image_path) 9 Открываем изображение
print(/"Изображение ‘' image_path)' успешно открыто.")
except FileWotFoundError;
print(/"Файл "{image_path}’ не найден. Проверьте правильность пути.")
except Exception as е:
print (f Произошла ошибка: {<}")
» Конвертация в другой формат (в PNG)
png_image - image.convert<"RGfi') » конвертация • RGfi
png-lmage.save("Image.png’) а сохранение как png
print("изображение успешно сконвертировано и сохранено как "image.png".“)
9 Показ оригинального и конвертированного изображений рядом
fig, axes pit.subplots(l, 2, figsize»(12, 6)) в Создаем 1 ряд и 2 колонки
• Отображаем оригинальное иэображение
axes[в].imshow(image) 9 Отображаем изображение
axe*[0),axis(’off') • Отключаем оси
axes[0].set_tit1е("Оригинальное изображение")
а Отображаем конвертированное изображение
axes[l].imshow(png_image) • Отображаем конвертированное изображение
axes(l).axisf’off’) а Отключаем оси
axes[l].set_title(~KoHBepTHpoea№«oe Изображение (PN6)“)
plt.tight_layout() 9 Обеспечиваем равномерное распределение подграфиков
plt.Show() 9 Показать изобретения Заключение
— иэображение "/conrent7Plc.jpg’ успело открыто.
Изображение успешно сконвертировано и сохранено как ’image.png'.
plt.shcwQ • Показать изображения Заключение
— Изображение '/contentfPic.jpg' успешно открыто.
Изображение успеяма сконвертировано и сохранено как 'feage.prg'.
Оригинальное Изображение
Конвертирс» энное Изображение (PNG)
Ipip install pydub
Рис. 6.26(1)
Давайте пройдемся по каждому шагу кода и поймем, как происходит про-
цесс открытия изображения, конвертация в другой формат и вывод ориги-
нального и конвертированного изображений рядом.
Табл. 6.9
Код Пояснение
Импортирование необходимых библиотек: from PIL import Image import matplotlib.pyplot as pit PIL (Pillow) — это библиотека для работы с изображениями в Python, которая позволя- ет открывать, изменять и сохранять их. Matplotlib — это библиотека для визуализа- ции данных, которая также используется для отображения изображений
Открытие изображения: image jpath = '/ccntent/Pic.jpg' # Путь к изображению try: image = Image.open(imagejpath) * Открываем изображение: print(f"Изображение ‘{image_path}' успешно открыто.") except FileNotFoundError: print(Г'Файл '(image jiathj' не най- ден. Проверьте правильность пути.") except Exception as e: print(f"Произошла ошибка: {e)") Указываем путь к изображению. Если мы ра- ботаем в Google Colab, изображение должно находиться в директории /content, С помощью Image.open () открываем его. Если файл не найден, срабатывает блок except, который сообщает об ошибке Код для открытия изображения image path = '/content/Pic.jpg' # Путь к изображению. Эта строка задает переменную image path, которая содержит путь к файлу, который мы хотим открыть. В данном случае изображе- ние называется Pic.jpg и находится в дирек- тории /content.
Код Пояснение
Сохраняем путь в переменной, чтобы потом использовать его для открытия изображе- ния. Это удобно и позволяет легко менять адрес файла, если это потребуется, try: начинает блок try, который позволяет обрабатывать ошибки, возникающие при открытии файла. Использование блока try-except помогает избежать краха программы. Если произой- дет какая-либо ошибка (например, файл не найден), программа не остановится, а перей- дет к обработчику ошибок. image = Image.open(imagejpath) * Открываем изображение Используем метод Image.open() из библио- теки Pillow для открытия изображения по указанному пути, сохраняем его в перемен- ной image. Мы хотим загрузить изображение в память, чтобы затем с ним работать (например, отоб- ражать, изменять, конвертировать и т. д.). print(f"Изображение '{image path}' успешно открыто.") Если изображение успешно открыто, на экран выводится подтверждающее сообще- ние. Используем форматированные строки (f-string) для включения переменной image path в текст сообщения. Это полезная обратная связь для пользо- вателя, чтобы он знал, что изображение загружено без ошибок. except FileMotFoundError: начинает блок обработки ошибок except, который будет выполняться, если на этапе try произойдет ошибка типа FileNotFoundError (например, если указанный файл не найден). Это позволяет коду реагировать на специ- фические ошибки, которые могут произойти при работе с файлами print(f"$aftn '{image_pathj' не найден. Про- верьте правильность пути.") Если возникла ошибка FileKotFoundError, выводит сообщение, что файл не найден, и предлагает пользователю проверить пра- вильность пути. Это помогает пользователю понять, почему изображение не загрузилось и что нужно сделать для решения проблемы — прове- рить правильность указанного пути. except Exception as е: Этот блок except обрабатывает все остальные виды ошибок (не только FileNotFoundErrcr) и сохраняет информацию об ошибке в переменной е.
Код Пояснение
Это гарантирует, что, если произойдет другая ошибка (например, в разрешении до- ступа к файлу), она также будет перехвачена и программа не закроется без объяснений, print(f"Произошла ошибка: (е)") выводит сообщение об ошибке на экран с описанием, что конкретно пс шло не гак. Переменная е содержит информацию о произошедшей ошибке. Это полезная инф. >рмация для отладки — помогает понять, в чем заключалась пробле- ма, если его не удалось открыть. Таким образом, код отвечает за безопасное открытие изображения и обработку воз- можных ошибок Он информирует о статусе выполнения (успех или ошибка) и предо- ставляет рекомендации по исправлению ошибок, если они есть
Конвертация в другой формат: png_iirage = iir.age.ccn ver г ('RGB') ? Конвертация ь RGB pr.g_image. save ('image, png') # Сохра- нение как PNG print("Изображение успешно сконверти- ровано и сохранено как 'image.png'.") image.осnvert('RGF'): конвертирует изоб- ражение в цветовое пространство RGB Это может быть полезно, когда нужно гаранти ровать, что изображение имеет правильный цветовой формат для сохранения в PNG png_image.save('image.png') : сохраняет кон- вертированное изображение в формате PNG. Указано имя файла, под которым изображе- ние будет сохранено
Показ оригинального и конвертиро- ванного изображений рядом: fig, axes = pit.subplots(1, 2, figsize*(12, 6)) Создаем 1 ряд и 2 колонки. pit.subplots(1, 2, figsize-(12, 6)) создает фигуру, в которой будет 1 ряд с 2 колонками для подграфиков. Размер фигуры задается через параметр figsize
1 Отображаем оригинальное изображение axes[2].imshow(image) S Отображаем изображение axes[0].axis('off') # Отключаем оси axes[2].set_titie("Оригинальное Изоб- ражение") axes (0 ]. imshow (image; отображает ориги- нальное изображение в первом подграфике (axes [0]). axes {0] .axis ('off'): отключает оси, чтобы они не мешали просмотру изображения axes JO].set_title("Оригинальное Изображе- ние") : задает заголовок для первого подгра- фика
1 Отображаем конвертированное изоб- ражение axes[1].rmshow(png_image) # Отобража- ем конвертированное изображение axes[1].axis('off') 1 Отключаем оси axes[ 1 ].set_ titie("Конвертированное Изображение (PNG)") axes 11]. imshow (png_image): отображает конвертированное изображение во и тором подграфике (axes [ 1 ]). axes [ 1 ]. axis ('of f'): отключает оси для второго подграфика. axes[1].set_title("Конвертированное Изобра- жение (PNG)"): задает заголовок для второго подграфика
pjt.tight_layout() i Обеспечиваем равномерное распределение псдграфиков pit.show!) I Показать изображения plt.tight_laycut () автоматически подстра- ивает подграфики так, чтобы они не пересе- кались. pit.shew (): отображает всю фигуру с подгра- фиками
Вставьте этот код в ячейку Google Colab, убедившись, что изображение
Pic.jpg загружено в директорию /content. После выполнения кода вы увиди-
те окно с двумя изображениями рядом: оригинальным и конвертированным
в формате PNG.
Мы рассмотрели основные операции, которые можно выполнять с изоб-
ражениями в Python. Библиотека Pillow предоставляет широкий спектр воз-
можностей для обработки изображений, включая операции с цветом, нало-
жение текста, создание миниатюр, технические преобразования и многое
другое. Можно комбинировать различные функции и библиотеки для дости-
жения более сложных задач в обработке изображений.
Работа со звуковыми файлами
Для обработки аудиофайлов в Python чаще всего используется библиотека
Pydub [85], предоставляющая инструменты для манипуляции звуковыми
данными.
Pydub позволяет легко манипулировать аудиофайлами, а библиотека
librosa используется для анализа музыки и аудиосигналов.
Мы будем использовать Pydub. Также можно обратит ься к IPython.display
для воспроизведения аудио прямо в Google Colab.
Для демонстрации возможностей библиотеки загрузим аудиофайл sound.
mp3 в Colab.
:= Файлы ГЗ X
в Э е п
ь
< >
» sample_data
В P'c.jpg
В books xml
В data (l).csv
В тпаде.р
В original, oks.json
В outputs
В <esizeo age.jpg
В sound.mp3
Рис. 6.26(2)
Установка необходимых библиотек
Если вы еще не установили библиотеки, выполните следующий код в ячейке
Colab:
Jpip install pydub
!apt-get install ffmpeg # Установить ffmpeg для работы с форматами аудио
1 pip install pydub
Requirement already satisfied: pydub In /usr/local/lib/python3.12/dist-package* * (0.25.1)
Q !apt-get install ffmpeg » Установить ffmpeg для работы с форматами аудис]
••• Reading package lists... Done
Building dependency tree... Done
Reading state information... Dore
ffmpeg is already the newest version (7:4.4.2 0ubuntu0.22.04.i).
0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded.
from pydub import AudioSegment
from pydub.playback Import play
from IPython.display import Audio, display
а Загрузка аудиофайла
audiopath - '/content/sound.mp3
audio - Audiosegaent.from_fileiaudio_path)
рНпЦ’Аудиофайя успеаю загружен.")
9 Получаем информацию об аудиофайле
duration - len(audio) • Длительность а миллисекундах
print(f’Длительность аудиофайла: (duration / 1000} секунд.’)
• Воспроизведение аудиофайла
play(audio) * Воспроизводит аудиофайл
* Обрезка аудиофайла (первый 5 секунд)
start.time - 0 а Начало
endtime 5ОО0 » Конец (5 секунд)
Рис. 6.27. Пример кода для работы с аудиофайлом
Вот несколько операций, которые вы можете выполнить с аудиофайлом
sound, mp3 с помощью Pydub:
1. Импорт библиотеки:
from pydub import AudioSegment
from pydub.playback import play
from IPython.display Import Audie, display
Iplp Injtell pydub
Requirement already satisfied: pydub in /usr/local/lib/pytborJ.12/dist-packages (0.2S.1)
!apt-get Install ffmpeg • Установить ffmpeg для работе с формата»» аудио
Reading package lists... Done
Building dependency tree... Done
Reading state information... Dore
ffmpeg is already the newest version (7:4.4.2 Bubuntue.22.04.1).
0 upgraded. 0 newly installed. 0 to remove and 2 not upgraded.
{J from pydub Import AudloSegmert
free pydub.playback import play
from I Python, display l^xsrt Audio, display
••• /usr/local/lib/python3.12/dlst°packages/pydub/utlls.py:3W SyntaxMamlng: invalid escape sequence *\(‘
m - re.match('((su]([0-9]{i.2))p>) \(((0-9]{l,2}) Mt\)S'. token)
/usr/local/lib/python3.12/dlst-packages/pydub/utlls.py:301: SyntaxWamlng: invalid escape sequence *\(’
m2 - re.match(*((su]((0-9]{l,2))p?)( \(default\))H*. token)
/u$r/local/lib/python3.12/dist-packages/pydub/utils.py:310: Syntaxwaming: invalid escape sequence *\(’
elif re.matchf“(flt)p?( \(default\))?S*. token):
/usr/local/lib/python3.12/dlst-packages/pydub/utlls.py;3J4: Syntaxwarring: Invalid escape sequence *\(’
elif re.match(*(dbl)p?< \(default\))token);
e Загрузка аудиофайла
audiopath '/content/sound.mp3'
audio « AudioSegment.from_flle(audio_path)
prlnt("Аудиофайл успммо aarружей.**)
• получаем информации об аудиофайле
duration « leniaudio) Длительность а икалисекундах
print (^Длительность аудиофайла: duration / 1000} секунд.")
Рис. 6.28
2. Загрузка аудиофайла:
f Загрузка аудиофайла
audic_path = '/content/sound.mp3'
audio = AjdioSegnent.froir._file (audio_path)
print("Аудиофайл успешно загружен.")
from pydub.playback import play
from IPython.display import Audio, display
— /usr/local/lib/python3.12/dist-packages/pydub/utils.py:300: Syntaxwarning: invalid escape sequence *\(’
• re.match(’([su]([0-9]{l,2))p?) \(([0-9]{l,2)) bit\)$', token)
/usr/local/lib/python3.12/dist°packages/pydub/utils.py:301: Syntaxwarning: invalid escape sequence *\('
2 re.match('((su]((0-9]{l,2})p?)( \(default\))?$’, token)
/usr/local/lib/python3.12/dist-packages/pydub/utils.py:310: Syntaxwarning: invalid escape sequence "\('
elif re.match(‘(flt)p?( \(default\))?$', token):
/usr/local/lib/python3.12/dist-packages/pydub/utils.py:314: Syntaxwarning: invalid escape sequence "\(*
elif re.matchf'(<ibl)p?( \(default\))?S‘, token):
___________________________________________________________ + Код ____ + Текст _________________________________
Q и Загрузка аудиофайла |
audiopath '/content/sound.дрэ’
audio - AudioSegment.from_file(audio_path)
print("Аудиофайл успешно загружен.")
— Аудиофайл успешно загружен.
е получаем информацию об аудиофайле
duration • len(audio) • Длительность в миллисекундах
print(f“Длительность аудиофайла: {duration / 1000} секунд.")
« воспроизведение аудиофайла
play(audio) А Воспроизводит аудиофайл
м Обрезка аудиофайла (первый 5 секунд)
3. Проверка информации об аудиофайле:
? Получаем информацию об аудиофайле
duration = len(audio) # Длительность в миллисекундах
print(f"Длительность аудиофайла: {duration / 1000} секунд.")
from pydub.playback import play
from IPython.display import Audio, display
/usr/l<xal/lib/python3.12/dist packagrs/pydub/utils.py:300: Syntaxwarning: invalid escape sequence
и • re.match(‘([su]((0 9](l,2))p>) \(([0 9](1,2)) bit\)$'( rotten)
/usr/local/lib/python3.i2/dist packages/pydub/utils.py:301: Syntaxwarning: invalid escape sequence '\C
2 - re.match(’([su]([0 9](1.2})p?)( \(default\))?$', token)
/usr/local/lib/python3.12/dist packages/pydub/utils.py:31&' syntaxwarning; invalid escape sequence
elif re.match! (flt)p?( \(detault\))’$', token):
/usc/local/lib/pytnon3.12/dist pacKages/pydub/utils.py:314: Syntaxwarning invalid «scape sequence '\('
elif re.match('(dbl)p?( \(default\))?$', token):
» Загрузка аудиофайла
audio path » '/contcnt/sourid.inp3'
audio - Audiosegment .frocn f ileiaudio_path)
print("Аудиофайл успетно загружен.')
Аудиофайл успешно загружен.
Q # Получаем информацию об аудиофайле
duration - len(audio) * * Длительноегь е миллисекундах
print(f"Длительность аудиофайла: {duration / 1000] секунд.')
••* Длительность аудиофайла: с.. 165 секунд.
• Воспроизведение аудиофайла
playiaudio) J воспроизводит аудиофайл
Рис. 6.30
4. Воспроизведение аудиофайла:
f Воспроизведение аудиофайла
play(audio) ♦ Воспроизводит аудиофайл
рг ^({^длительность аудиофайла: {duration / 1009) секунд.")
Длительность аудиофайла: 6.165 секунд.
Q к Воспроизведение аудиофайла
play(audio) # воспроизводит аудиофайл
t Обрезка аудиофайла (первый 5 секунд)
starttime - о # Начало
endtime 5000 « Конец (5 секунд)
cut^audio audio[start_tiae:end_ttae]
# Сохранение обрезанного аудиофайла
cut_aud io.export(*/content/cut_sound, mp3', format- * mp3 *)
print("Обрезанное аудио сохранено как 'cut_sound.mp3'.")
• Увеличение громкости на 6 дБ
louder audio = audio + б й Увеличение громкости
louder audio.export(*/content/louder sound.дрз*, format-'ирз’)
рг1п1(”Увеличенная громкость аудио сохранена как 'loudcrsound.mp3’.")
• воспроизведение обрезанного аудиофайла
display(Audio('/content/cut sound.mp3'))
5. Обрезка аудиофайла:
f Обрезка аудиофайла (первый 5 секунд)
starttime = 0 # Начало
eno time = 5009 i Конец (5 секунд)
cut_audio = audio[start_time:end_time]
print(f"Длительность аудиофайла: -duration / 1000) секунд.")
Длительность аудиофайла: 6.165 секунд.
« Воспроизведение аудиофайла
play (.audio; Воспроизводит аудиофайл
, ф Ф В : —
0 • Обрезка Йудмбфэйла (первый 5 секунд)
starttime • 0 я начало
endtime 5000 • Конец (5 секунд)
cut_audio audio)start_time:end_time]
• Сохранение обрезанного аудиофайла
cutaudio.export('/content/cutsound.mp3* *, formatmp3')
print(“Обрезанное аудио coxpatw*» как 'cut_sound.mp3’.")
s увеличение громкости на 6 ль
louder_audio audio ♦ 6 I Увеличение громкости
louderaudic. export (’ /content/loudersound-ирз ’, format - mp3 ’)
print(“Увеличенная громкость аудио сохранена как 'louder_sound.mp3'.“)
• Воспроизведение обрезанного аудиофайла
display(Audio(’/content/cut sound.mp3'))
Рис. 6.32
6. Сохранение обрезанного аудиофайла:
# Сохранение обрезанного аудиофайла
cut_audio.export('/content/cut_sound.mp3', format-'mp3')
print("Обрезанное аудио сохранено как 'cut_sound.mp3'.")
play(audio) » Воспроизводит аудиофайл
• Обрезка аудиофайла (переьЛ 5 секунд)
start tine - е а начало
end_time » 5000 • конец (5 секунд)
cut_audio audio)start_time:end .time]
0 ж Сохранение обрезанного аудиофайла
cut_audio.export('/content/cutscund.mp?', format»'mp3’)
print ("Обрезанное аудио сохранено как Ucut_sound.mp3'.")
— Обрезанное аудио сохранено как ,cut_sound.mp3'.
Ф Ф 0
• Увеличение громкости на 6 дБ
louder_audio - audio • 6 « Увеличение громкости
louder audio.export('/content/louder^sound.mp3', format ’mp3’)
print("Увеличенная громкость аудио сохранена как ’louder_sound.mp3'
• Воспроизведение обрезанного аудиофайла
di$play(AudioC‘/content/cut-Sound-mpa*))
display(Audio)'/content/sound.mp3 *))
Ipip install requests
7. Добавление эффекта изменения громкости:
ff Увеличение громкости на 6 дБ
louder audio = audio + 6 # Увеличение громкости
louder audio.export('/content/louder sound.mp3', format='mp3')
print("Увеличенная громкость аудио сохранена как 'louder_sound.mp3'.")
Файлы
Q С С <£?
Gr
► И sampie.data
ft РМР9
ft books xml
ft cut. к пч>3
ft data ( v
ft
ft louaei. sound mp3
ft oiigmat_books json
ft output csv
ft res^eajmage.jpg
ft sound mp3
4* Аудиофайл успешно загружай.
(3 X
(423 • Получаем информацию об аудиофайле
duration « len(audio) » Длительность а миллисекундах
рг1п^/"Длительность аудиофайла; (duration / 1000) секунд.**)
Длительность аудиофайла: 262.635 секунд.
t44] * Воспроизведение аудиофайла
ск play(audio) В Воспроизводит аудиофайл
/ [45] а Обрезка аудиофайла (первый 5 секунд)
ом start_tiBK * 0 # Начало
end-time » 5000 • Конец (5 секунд)
cut_audio audio[»tart_time:end_ti»e]
t4*] • Сохранение обрезанного аудиофайла
cut_Budio.export( */content/cut sound.nip31, fогамt*’ap3’)
print("Обрезанное аудио сохранено как ’cut_sound.mp3'.")
~»у Обрезанное аудио сохранено как 'cut_sound.mp3'.
О * Увеличение громкости на 6 дБ
см louder_audio audio *6 • Увеличение громкости
louder.audio.export(*/content/lovder^tovndJET- format»'ирЗ')
print("Увеличенная громкость аудио сохранена как 'louder_sound.«p3'.")
Увеличенная громкость аудио сохранена как 'louder_sound.mp3*.
Рис. 6.34
8. Воспроизведение обрезанного аудиофайла или измененной громкости:
# Воспроизведение обрезанного аудиофайла
display(Audio(Vcontent/cut sound.mp3'))
я Обрезки аудиофайла (первый 5 секунд)
start .time • о я Начало
end_tine « 5В00 я Конец (S секунд)
cutaudio = audio[start_time:end_time]
и Сохранение обрезанного аудиофайла
cut audio.export;'/<ontent/cut sound.mp3', format'mp3')
print("Обрезанное аудио сохранено как 'cut_sound.mp3'.")
Обрезанное аудио (охранено как 'cut_sound.mp3'.
# Увеличение громкое гм на 6 дЬ
louder audio = audio + 6 я Увеличение громкости
louder_audio.export( •/content/loudersound.mpS', format='mp3’)
print("Увеличенная громкость аудио сохранена как 'louder_sound.mp3'.")
Увеличенная громкость аудио сохранена как 'louder sound.mp3'.
Q # Воспроизведение обрезанного аудиофайла
display(Audio('/content/cut sound.mp3'))
► 0:00/0.05 —------------ «•) :
.____________________________________________________________________________
display(Audin( */content/sound.nip3‘))
Рис. 6.35
Вот полный пример, который объединяет все вышеперечисленные шаги:
# Установка необходимых библиотек
!pip install pydub
lapt-get install ffmpeg 4 Установка ffmpeg
# Импортируем библиотеки
from pydub import AudioSegment
from pydub.playback import play
from IPython.display import Audio, display
# Загрузка аудиофайла
audio path = '/content/Sound.mp3'
audio = AudioSegment.from_file(audio_path)
print("Аудиофайл успешно загружен.")
# Получаем информацию об аудиофайле
duration = len(audio) # Длительность в миллисекундах
print(f"Длительность аудиофайла: {duration / 1ССС} секунд.")
# Воспроизведение аудиофайла
play(audio) $ Воспроизводит аудиофайл
# Обрезка аудиофайла (первый 5 секунд)
start_time = 0 # Начало
end_time = 5С00 * Конец (5 секунд)
cut_auaio = audio[start_time:end_time]
# Сохранение обрезанного аудиофайла
cut_audio.export('/ccntent/cut_scund.mp3', format='mp3')
print("Обрезанное аудио сохранено как 'cut sound.irp3'.")
# Увеличение громкости на 6 дБ
lcuder_audio = audio + 6 f Увеличение громкости
lcuder_audio.export('/content/louder sound.mp3', format='mp3')
print ("Увеличенная громкость аудио сохранена как 'louder sound.ir.p3'.")
# Воспроизведение обрезанного аудиофайла
display(Audio('/content/cut sound.mp3'))
Взаимодействие с веб-API
Библиотека requests для HTTP-запросов
Веб-API (Application Programming Interface) представляет собой интер-
фейс, который позволяет программному обеспечению взаимодействовать
с другими системами через интернет. В контексте Python взаимодействие
с веб-АР1 [86] осуществляется в основном с помощью HTTP-запросов, что
позволяет получать и отправлять данные в формате JSON, XML и других
структурированных формах.
Основная терминология
Говоря о взаимодействии с веб-API, мы часто имеем в виду отправку и по-
лучение информации через интернет. Для этого используются специальные
команды — HTTP-запросы. Они помогают нам «говорить» с API, который,
по сути, является средством связи между нашим приложением и удаленным
сервером.
Вот основные команды, которые мы используем:
1. GET — для получения информации. Например, запрашивая погоду через
API, мы используем метод GET, чтобы получить данные о текущей темпера-
туре.
2. POST — для отправки данных на сервер. Например, заполняя форму на
сайте и отправляя ее, мы используем метод POST, чтобы передать информа-
цию (имя, email и т. д.) на сервер.
3. PUT — для обновления существующей информации. Например, изменяя
данные своего профиля на сайте, мы используем PUT, чтобы обновить их на
сервере.
4. DELETE — для удаления какой-либо информации. Например, решив уда-
лить свой аккаунт на сайте, мы отправляем запрос через метод DELETE, чтобы
сервер удалил наши данные.
Каждый из этих методов указывает на то, что именно мы хотим сделать
с данными. Важно понимать, что веб-API — это просто интерфейс для обще-
ния, а НТТР-запросы — это язык, на котором мы с ним общаемся.
В большинстве случаев данные передаются в формате JSON, потому что
он легкий и читабельный. Тем не менее поддерживаются и другие, такие как
XML и обычный текст.
Библиотеки для работы с веб-АР1
Существует несколько библиотек, которые упрощают процесс работы с веб-
API в Python. Наиболее распространена Requests, которая предоставляет
простой и понятный интерфейс для выполнения НТТР-запросов.
Для работы с JSON-данными обычно используется стандартный модуль
json, который позволяет сериализовать и десериализовать такие данные.
Пример использования
Давайте разберемся с темой взаимодействия с веб-API шаг за шагом, что-
бы стало понятнее. Объясним каждую часть процесса простым языком. На-
чнем с основ и перейдем к более сложным аспектам.
Что такое веб-API?
Веб-API — это способ, с помощью которого программа или приложение
запрашивает данные у другого приложения или веб-сервиса через интернет.
Можно представить API как меню в ресторане: вы делаете выбор и заказыва-
ете, а кухня (сервис) готовит ваше блюдо (данные) и приносит его вам.
Установка библиотеки Requests
Чтобы работать с веб-API в Python, мы будем использовать библиотеку
Requests. Это удобный инструмент, который помогает отправлять запросы
и получать ответы.
Если вы работаете в Google Colab, достаточно выполнить команду, кото-
рая установит библиотеку:
Ipip install requests
Если вы используете локальную среду (например, Anaconda или обычный
терминал), код будет такой же, но без !:
pip install requests
display(Audio( '/content/sowd. mp3' ))
Q Ipip install requests
Ф Ф 4/ s s —
Requirewnt already satisfied: requests in /usr/locdl/lib/pytbon3.12/dist-packages (2.32,4)
Requirement already satisfied: charset normalizer<4,>»2 in /usr/local/lib/python3.12/dist-packages (free requests) (3.4.4)
Requirement already satisfied: idna<4,>-2.5 in /usr/local/lib/python3.i2/dist-packages (from requests) (3.11)
Requirement already satisfied: urllibl<3,>•!.21.1 in /usr/local/lib/python3.12/dist packages (from requests) (2.5.0)
Requirement already satisfied: certifi>-2017.4.17 in /usr/local/lib/pythcn3.12/dist-pdckages (from requests) (2026.1.4)
pip install requests
import requests • Импортируем библиотеку, чтобы использовать ее функции
response - requests.get(,https://jsonplaceholder.typicode.com/todos/l') » Отправляем запрос на получение дмишх
if response.status_code * 200: 9 проверяем, успешен ли запрос (статус 200 успех)
data response.json() • Преобразуем ответ в формат 3S0H (если он в этом формате)
print (data) • выводим лолученгтю данные на экран
else:
print (Сеймом (response, st Mus_code): response, text}’) • Если овмбха, выводим сообвеннс об ошибке
payload « {'key': 'value'} я создаем словарь с данными, которые хотим отправить
Рис. 6.36
Основы НТТР-запросов
Теперь, когда у нас есть библиотека, давайте попробуем выполнить НТТР-
запрос. Начнем с определения. НТТР-запрос — это команда, которую мы от-
правляем на сервер, чтобы что-то узнать или сделать. Все равно что задать
вопрос или сделать заказ.
Пример получения данных (GET-запрос):
1. Импортируем библиотеку:
import requests # Импортируем библиотеку, чтобы использовать ее функции
2. Отправляем GET-запрос:
response = requests.get('https://api.example.com/data') # Отправляем
запрос на получение данных
Используем метод get(), чтобы попросить сервер прислать нам данные.
'https://api.exair.ple.com/cata' — это пример URL, который вы можете за-
менить на настоящий API.
3. Проверяем, успешен ли запрос:
if response.status_code == 200: # Проверяем, успешен ли запрос (статус
200 - успех)
data = response.json() # Преобразуем ответ в формат JSON (если он
в этом формате)
print(data) i Выводим полученные данные на экран
else:
print(f"Ошибка |response.status cooe): {response.text}") у Если
ошибка, выводим сообщение об ошибке
response. status code — это код ответа от сервера. Если код 200, значит,
запрос успешен.
Если запрос не удался, мы получим другую ошибку, которую также напе-
чатаем.
4. Отправка данных (POST-запрос).
Теперь посмотрим, как отправить данные на сервер, используя метод POST.
• Создаем данные для отправки:
payload = {'key': 'value'} # Создаем словарь с данными, которые хотим
отправить
• Отправляем POST-запрос:
response = requests.pest('https://api.example.com/data', json=paylcad)
# Отправляем данные на сервер
Используем метод post (), чтобы отправить данные. json=paylcad указыва-
ет, что мы отправляем данные в формате JSON.
• Обрабатываем ответ:
if response.status_code == 201: * Статус 201 означает, что ресурс ус-
пешно создан
print("Данные успешно отправлены!")
else:
print(f"Ошибка {response.status code}: {response.text}")
5. Обработка ошибок.
Всегда важно учитывать возможность возникновения ошибок. Вот не-
сколько основных кодов ошибок:
• коды 200 — успешный запрос;
• коды 400 — ошибка клиента (например, неверный запрос);
• коды 500 — ошибка сервера (с сервером что-то не так).
С помощью статус-кодов можно управлять поведением программы, пока-
зывать пользователю подходящие сообщения и т. д.
Для взаимодействия с веб-сервисами и API в Python широко использует-
ся библиотека Requests, предоставляющая простой и удобный интерфейс для
выполнения НТТР-запросов.
Выполнение GET-запроса:
import requests
response = requests.get('https://api.github.com/users/alice')
data = response.json() # Автоматическая десериализация данных в формате
JSON
print(aata{'name'], data['public_repos'])
Алгоритм создания решения:
1, Импорт библиотеки. Импортируйте модуль requests, который предо-
ставляет возможности для выполнения НТТР-запросов.
2. Выполнение GET-запроса. Используйте метод requests .get () для отправ-
ки GET-запроса к указанному URL.
3. Десериализация ответа. Преобразуйте ответ в формате JSON в Python-
объект с помощью метода j son ().
4. Доступ к данным. Извлеките нужную информацию из полученного
объекта и выведите ее на экран.
Синтаксис используемых новых функций и причины их использования:
1. import requests импортирует библиотеку Requests, которая предостав-
ляет простой и удобный интерфейс для отправки НТТР-запросов.
2. requests.get('https://api.github.com/users/alice') выполняет GET-
запрос по указанному URL и возвращает объект ответа, который содержит
статус ответа, заголовки и тело ответа.
3. response.json() преобразует содержимое ответа в формате JSON
в Python-объект (например, словарь).
4. data ' 'name' ], datai'public_repcs'] дает доступ к элементам словаря
data для получения значения по ключам < name > и 'public_repos'.
Подробное объяснение каждой строки кода:
1. import requests импортирует библиотеку Requests, что позволяет ис-
пользовать ее функции для выполнения НТТР-запросов.
2. response = requests.get('https://api.grthub.com/users/alice') вы-
полняет GET-запрос к API GitHub по адресу: < https://api .github.com/users/
alice >. Результат запроса сохраняется в переменной response, которая содер-
жит все данные об ответе, включая статус и тело.
3. data = response, json() преобразует тело ответа в Python-словарь и со-
храняет его в переменной data. Это позволяет удобно работать с данными
в виде стандартных структур Python.
4. print (data [ 'name' ], data{'puolic repos']) выводит на экран значение,
связанное с ключом < name > и значением < public_repos > из словаря data, 'name'
соответствует имени пользователя GilHub, а <public repos > отображает ко-
личество его общедоступных репозиториев.
В этом коде вы видите, как с помощью библиотеки Requests можно выпол-
нить GFT-запрос к API GitHub для получения информации о пользователе.
Преобразование ответа в формате JSON в объект Python позволяет легко из-
влекать необходимые данные и выводить их на экран. Библиотека Requests
упрощает работу с HTTP-запросами, делая код более читаемым и удобным.
Передача параметров и установка заголовков запроса:
params = {'q': 'Python'}
heaaers = {'User-Agent': 'MyApp/1.9'}
response = requests.get ('https: //api.example. com/search', params=params,
headers=headers)
Передача параметров и установка заголовков запроса в HTTP позволяет
настраивать, как клиент (ваше приложение или скрипт) будет взаимодейс-
твовать с сервером, на который вы отправляете запрос. Это делается для того,
чтобы сервер мог понять, что именно вам нужно, а также чтобы идентифици-
ровать приложение.
Алгоритм создания решения:
1. Импорт библиотеки. Импортируйте модуль requests, который позво-
ляет отправлять НТТР-запросы.
2. Подготовка параметров запроса. Создайте словарь с параметрами, ко-
торые будут переданы серверу. Их можно использовать для фильтрации или
настройки ответа.
3. Подготовка заголовков запроса. Создайте словарь с заголовками. Заго-
ловки могут содержать информацию о клиенте, версии приложения или дру-
гие метаданные.
4. Выполнение GET-запроса. Используйте метод requests .get () для отправ-
ки GET-запроса, передавая параметры и заголовки.
Синтаксис используемых новых функций и причины их использования:
1. import requests импортирует внешний модуль requests, который ис-
пользуется для работы с HTTP-запросами.
2. params = {'q': 'Python'} создает словарь params, который будет со-
держать параметры запроса. В данном случае параметр q имеет значение
< Python >, что может использоваться для поиска по этому запросу на сервере.
3. headers = {'User-Agent': 'МуАрр/1.0'} создает словарь с заголовками
запроса. Значение ключа < User-Agent > указывает, какое приложение отправ-
ляет запрос (в данном случае <МуАрр/1.0 >).
4. response = requests.getf'https://api.example.com/search',
params=params, headers=headers) выполняет GET-занрос в заданный URL с уче-
том параметров и заголовков. Результат сохраняется в переменной response.
Объяснение:
1. params = {'q': 'Python'} — создание параметров. Вы создали словарь
params, в котором указали поиск по ключу 'q' со значением < Python >. Этот
параметр будет использоваться сервером для выполнения запроса.
2. headers = ('User-Agent': 'КуАрр/1.0'} — создание заголовков. Вы со-
здали словарь headers, в котором указали заголовок 'User-Agent'. Это значе-
ние информирует сервер, что запрос был отправлен приложением с названи-
ем Му Арр версии 1.0.
3. response = г equests. get ('https: //api. example. com/searcn', params=params,
headers=headers) — отправка GET-запроса. Вы выполняете GET-запрос по ука-
занному URL (<https://api.example.com/search>), передавая подготовленные
параметры и заголовки. Результат (например, ответ сервера) сохраняется в пе-
ременной response. Теперь вы можете использовать ее для доступа к информа-
ции, полученной от сервера, такой как данные и статус ответа.
В результате вы научились передавать параметры и устанавливать за-
головки при выполнении GET-запроса, что позволяет настроить общение
с сервером и получать именно ту информацию, которая вам нужна.
Обработка ошибок при выполнении НТТР-запросов:
try:
response = requests.get('https://api.example.com/data', timeout=5)
response.raise_fcr_status0 # Вызывает исключение при получении
кода ответа 4хх или 5хх
except requests.exceptions.HTTPError as err:
print(f"Ошибка HTTP: {err}")
Обработка ошибок при выполнении НТТР-запросов — важная часть ра-
боты с веб-API, которая помогает предотвратить сбои в вашем приложении
и правильно управлять ситуациями, когда что-то идет не так. С помощью
конструкции try и except вы можете перехватывать и обрабатывать исклю-
чения, возникающие при выполнении НТТР-запросов.
Алгоритм создания решения:
1. Убедитесь, что вы импортировали библиотеку Requests.
2. Поместите код, который может вызвать ошибку (например, запрос
к API), в блок try.
3. Отправьте HTTP-запрос с использованием библиотеки Requests. Уста-
новите таймаут, чтобы избежать зависания программы.
4. Используйте метод raise for status () для проверки, успешен ли запрос
(коды 2хх). Эго вызывает исключение, если сервер вернул статус ответов 4хх
или 5хх.
5. Используйте блок except, чтобы перехватить и обработать исключения,
возникающие в блоке try.
Синтаксис новых функций и почему мы их используем:
1. try: начинает блок кода, в котором мы будем обрабатывать исключения.
2. response = requests.get ('https://api.example.com/data', timeout=5)
выполняет HTTP GET-запрос в указанный URL. Установка timeout=5 означа-
ет, что запрос завершится, если сервер не ответит в течение 5 секунд.
3. response.raise for status() проверяет код ответа. Если сервер вернул
ответ с ошибкой (например, 404, 500 и т. д.), метод вызовет HTTPError и вы-
полнение перейдет к блоку except.
4. except requests.exceptions.HTTPError as err: перехватывает исключе-
ние HTTPError, которое возникает, когда статус ответа указывает на ошибку.
Присваивает возникшее исключение переменной err.
5. print (f "Ошибка HTTP: (err}") выводит сообщение об ошибке, используя
f-строку для форматирования.
Что делает каждая строчка:
1. try — начало блока кода, где будут выполняться действия, которые по-
тенциально могут вызвать ошибку.
2. response = requests.get('https://api.exarnple.com/data', timeout=5) —
выполнение GET-запроса к указанному URL и задание timecut, чтобы избе-
жать ожидания ответа от сервера. Если сервер не отвечает в течение 5 секунд,
возникнет исключение.
3. response.raise_fcr_status () вызывает исключение при получении кода
ответа 4хх или 5хх. Для проверки статуса ответа вызываем метод raise_for_
status (). Если сервер вернул статус, указывающий на ошибку (4хх или 5хх),
метод вызовет исключение HTTPError и выполнение перейдет к блоку except.
4. except requests.exceptions.HTTPError as err — обработка ошибок
HTTP. Если возникло исключение HTTPError, вы переходите в блок except, где
можете свободно управлять ошибкой. Исключение будет храниться в пере-
менной err.
5. print (f"Ошибка HTTP: {err}") —вывод сообщения об ошибке на экран,
чтобы мы о ней знали и могли видеть детали.
Таким образом, код предоставляет простой способ обработки ошибок при
выполнении HTTP-запросов, позволяя отслеживать проблемы в работе с API
и реагировать на них соответствующим образом. Это особенно важно при
работе с веб-сервисами, поскольку различные проблемы, такие как непра-
вильный URL, серверные ошибки или тайм-ауты, могут привести к сбоям
в приложении.
Практические примеры автоматизации
Скрипт для обработки логов:
import glob
import re
# Сбор всех файлов с расширением .log
for log file in glob.glob('legs/*.log'):
with open(log_file, 'r') as f:
for line in f:
if re.search(r'ERROR:', line):
print(f"Ошибка в файле (log file}: {line.strip()}")
Скрипт автоматически анализирует все лог-файлы в папке logs, ищет
строки, содержащие слово «ERROR», и выводит их на экран с указанием,
в каком файле была найдена ошибка.
Алгоритм создания решения:
1. Импортируйте необходимые модули, такие как glob, для работы с фай-
ловой системой и ге для работы с регулярными выражениями.
2. Используйте glob.globO для поиска всех файлов с расширением .log
в указанной папке.
3. Откройте и читайте построчно каждый найденный файл.
4. Проверьте, содержат ли строки запись об ошибке (ERROR:) с помощью
регулярного выражения.
5. Если строка содержит ошибку, выведите сообщение с указанием файла
и самой ошибки.
Синтаксис используемых функций и причины их использования:
1. import glob импортирует модуль glob, который позволяет находить
файлы и пути, соответствующие заданному шаблону.
2. import re импортирует модуль ге, который используется для работы
с регулярными выражениями.
3. glob.glob( 'logs/*.log') используется для получения списка всех фай-
лов с расширением Jog в папке logs.
4. with open (log file, 'r') as f: открывает каждый лог-файл в режиме
чтения и автоматически закрывает его по завершении работы.
5. re. search (г'ERROR:', line) проверяет, содержится ли подстрока ERROR:
в текущей строке. Если она найдена, возвращает соответствующий объект,
который можно использовать для проверки.
6. print(f"Сшибка в файле {log file}: {line.strip()}") выводит инфор-
мацию об ошибке на экран с указанием имени файла и текста ошибки (с уда-
лением пробелов и символов новой строки с помощью strip ()).
Что делает каждая строчка:
1.import glob
import re
Импорт необходимых библиотек — glob для работы с файлом и ге для
регулярных выражений.
2. for log file in glob.glob('logs/*.log'). Сбор файлов. Используем
glob.glob(} для поиска всех файлов с расширением log в папке logs и итери-
руем по каждому найденному файлу.
3. with open (log_file, 'г') as f. Чтение лог-файла. Открываем файл в ре-
жиме чтения (< г >), чтобы начать его обработку. Использование with гаранти-
рует, что файл будет закрыт автоматически после выхода из блока.
4. for line in f. Итерация по строкам. Проходим по каждой строке в от-
крытом лог-файле.
5. if re. search (г'ERROR:', line) .Поиск ошибки. Проверяем, имеется ли в те-
кущей строке подстрока ERROR:. Если да, то будет выполнен следующий шаг.
6. print(f"Ошибка в файле {log_file}: (line.strip()}"). Вывод ошибки.
Если строка содержит ошибку, выводим на экран сообщение с указанием име-
ни файла и текстом ошибки, удаляя лишние пробелы с помощью strip ().
Этот скрипт предоставляет простой, но мощный способ автоматической
обработки лог-файлов для поиска и отображения записей об ошибках. Он
может быть легко адаптирован под различные задачи анализа логов, такие
как фильтрация по другим критериям или запись результатов в отчет вместо
вывода на экран.
Конвертация данных из CSV в JSON:
import csv
import json
csv_data = [J
with open('input.csv', 'r') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
csv_data.append(row)
with open('output.json', 'w') as jsonfile:
jsen.dump(csv_data, jsonfile, indent=2) i Форматирование JSON для
удобства чтения
Скрипт считывает данные из CSV-файла, преобразует их в формат JSON
и сохраняет в новый файл. Это удобно, когда вы хотите работать с данными
в формате, более подходящем для веб-приложений или передачи по Сети.
Алгоритм:
1. Импортируйте необходимые модули csv и json.
2. Откройте CSV-файл и используйте csv.DictReader для считывания
данных. Это создаст словарь для каждой строки, где ключи — это заголовки
столбцов.
3. Откройте (или создайте) JSON-файл и используйте json.dump() для за-
писи данных в формате JSON.
Синтаксис используемых функций и причины их использования:
1. import csv импортирует модуль csv, который позволяет удобно рабо-
тать с CSV файлами.
2. import json импортирует модуль json, который предоставляет возмож-
ности для работы с JSON-форматом.
3. csv.DictReader (csvfile) используется для чтения CSV-файла и автома-
тического преобразования каждой строки в словарь, где ключи — названия
заголовков.
4. зsen.dump(csv_data, jsonfile, indent=2) записывает список словарей
в JSON-файл jsonfile, с форматированием на уровне двух пробелов для
удобства чтения.
Что делает каждая строчка:
1. import csv
import json
Импорт библиотек. Импортируем модули csv и json, чтобы использовать
их функционал для работы с соответствующими форматами данных.
2. csv_data = [ ] — создание списка для данных. Создаем пустой список
csv data для хранения строк данных из CSV-файла в виде словарей.
3. with open ('input, csv', 'r') as csvfile — открытие CSV-файла. Откры-
ваем файл input.csv в режиме чтения (<г>). Конструкция with гарантирует,
что файл будет корректно закрыт после завершения работы.
4. reader = csv.DictReader (csvfile) — чтение данных. Создаем объект
reader, который читает строки из CSV-файла и преобразует их в словари с по-
мощью DictReader. Каждый заголовок столбца становится ключом в словаре.
5. for row in reader:
os\ data.append(row)
Сбор данных. Проходим по каждой строке (словарю) в объекте reader
и добавляем каждый словарь в список csv_data.
6. with open ('output, json', V) as jsonfile — открытие JSON-файла для
записи. Открываем (или создаем) файл output .json в режиме записи (< w >).
7. json.dump (csvdata, jsonfile, indent=2) —запись данных в JSON.
Используем json.dump() для записи данных из списка csv_data в файл
jsonfile. Параметр indent=2 делает JSON-файл более читаемы.м, добавляя
отступы.
Таким образом, ваш скрипт легко конвертирует данные из формата CSV
в JSON, что делает его полезным инструментом для работы с данными, осо-
бенно в веб-приложениях или при обмене информации между системами.
С помощью этого подхода вы можете легко адаптировать скрипт для обра-
ботки различных CSV-файлов и других типов данных.
В этой главе мы рассмотрели основные аспекты работы с файлами и ката-
логами в Python, включая чтение и запись текстовых данных, манипуляции
со структурированными данными в форматах CSV, JSON и XML, а также об-
работку медиафайлов. Особое внимание уделели вопросам взаимодействия
с веб-API с использованием библиотеки Requests. Полученные знания и на-
выки — основа для разработки сложных систем автоматизации и анализа
данных, которая открывает широкие возможности для применения в раз-
личных областях, таких как машинное обучение, анализ больших данных
и разработка веб-приложений.
Выводы
Глава дает комплексный обзор инструментов Python для работы с данны-
ми — от базовых файловых операций до взаимодействия с API и обработки
медиа. Ниже систематизированы ключевые аспекты.
1. Вазовые операции с файдами
Открытие файлов- используется встроенная функция open () с режи-
мами:
‘г’ — чтение;
‘w’ — запись (пересоздание);
а’ — добавление;
‘г+’ — чтение и запись;
Ь’ — бинарный режим.
Безопасность: контекстный менеджер with гарантирует корректное за-
крытие файла даже при ошибках.
Кодировка: обязательно указывать encoding=’utf-8’ для поддержки мно-
гоязычных данных.
2. Чтение и запись данных
Методы чтения
• read () — все содержимое;
♦ readline () — построчно;
• readlir.es () — список строк.
Методы записи:
• write () — строка;
• writelines 0 —список строк.
Особенность для CSV; при записи указывать newline=” (предотвращает
лишние пустые строки в Windows).
3. Обработка ошибок
Использовать блоки tryexcept для перехвата исключений:
• FileNotFoundError — файл нс найден;
• PermissionError — нет прав доступа;
• иные системные ошибки.
Критично для производственных сценариев с нештатными входными
данными.
4. Работа с структурированными данными
CSV (модуль csv):
♦ csv.reader — базовое чтение;
• csv.DictReader — доступ к столбцам по именам (повышает читаемость);
• рекомендация: очищать заголовки (например, strip ()) перед обработкой.
JSON (модуль json):
Сериализация: json.duinpO с параметрами:
• ensure_ascii=False — сохранение неАЗСП символов;
• indent=4 — читаемые отступы;
• encoding='utf-8’ — корректная кодировка.
Десериализация; json.load() — преобразование в структуры Python.
XML (модуль xml.etree.ElementTree):
Иерархическая структура с единственным корневым элементом.
Основные методы:
• ET.Elenient() — создание корневого узла;
• ET.SubElement() — добавление вложенных элементов;
• tree.write() — сохранение с декларацией XML;
• findall(), get(), find().text — извлечение данных.
Преимущества: гибкость, совместимость, возможность валидации
(DTD/XSD).
5. Управление файловой системой
Библиотеки: os, shutil, palhlib.
Возможности:
• создание, удаление, переименование файлов/каталогов;
• навигация по директориям;
• копирование и перемещение файлов.
6. Работа с медиафайлами
Изображения (Pillow + Matplotlib):
Загрузка и отображение (Image.open (), pit.imshow()).
Трансформации:
• изменение размера (resi ze ());
• обрезка (crop ());
• поворот (rotate ());
• фильтры (ImageFilter.BLUR).
Конвертация форматов (например, JPEG <-> PNG).
Сохранение с контролем качества.
Рекомендации:
• оборачивать открытие файлов в tryexcept;
• использовать plt.axis(<off>) для скрытия осей;
• для больших изображений применять thumbnail () (сохранение про-
порций).
Аудио (Pydub + librosa):
Загрузка: AudioSegment.from file().
Анализ: длительность, битрейт, количество каналов.
Редактирование:
• обрезка (audiojstart:endj);
• изменение громкости (+6 дБ);
• объединение треков.
Экспорт в нужный формат.
Воспроизведение через IPython.di.splay.Audio.
Нюансы:
• для MP3 требуется ffmpeg (!apt-get install ffmpeg);
• длительность в миллисекундах (переводить в секунды);
• явно указывать формат при сохранении (forniat=>mp3>).
7. Взаимодействие с вебАР!
Библиотека: requests.
НТТРметоды:
• GET — запрос данных;
• POST — отправка данных;
♦ PUT — обновление;
* DELETE — удаление.
Ключевые функции:
• requests.get(url, params=params, headers=headers) — передача параметров
и заголовков;
• response.json() — десериализация JSON;
• response.status_code — проверка статуса (200 — успех);
• timeout — ограничение времени ожидания.
Обработка ошибок:
Блоки tryexcept для:
requests.exceptions.HTTPError;
requests.exceptions.! imeout;
requests.exceptions.ConnectionError.
Метод raise for status() — автоматическое исключение при 4xx/5xx.
Практические примеры:
• получение данных из API (например, GitHub);
• отправка форм через POST (json=payload);
• аутентификация через заголовки (Authorization).
Рекомендации:
• всегда указывать timeout;
• проверять Content-Type в заголовках;
• для отладки выводить response.text при ошибках.
8. Автоматизация и скрипты
Примеры:
Анализ логов, поиск строк с «ERROR:» через glob и ге.
Конвертация CSV > JSON: использование csv.DictReader и json.dumpO.
Итоговые выводы
Глава охватывает полный цикл работы сданными в Python:
Базовые файловые операции (открытие, чтение, запись, закрытие).
Обработка ошибок для устойчивости к нештатным ситуациям.
Работа с табличными (CSV) и иерархическими (JSON, XML) данными.
Манипуляции с файловой системой (os, shutil, pathlib).
Обработка медиафайлов (изображения, аудио).
Взаимодействие с вебАР! (requests).
Автоматизация рутинных задач (скрипты для логов, конвертации).
Значимость для инженерии данных:
Навыки работы с файлами и форматами — фундамент ETL-пайплайнов.
Умение обрабатывать медиафайлы критично для компьютерного зрения
и аудиоанализа.
Знание API позволяет интегрировать внешние сервисы (облачные храни-
лища, NLP-модели).
Автоматизация снижает трудозатраты и ошибки.
Рекомендации для практики:
Использовать виртуальные окружения (venv) для изоляции зависимостей.
Всегда указывать кодировку utf-8.
Документировать API-запросы (URL, параметры, заголовки).
Применять logging вместо print () в продакшене.
Тестировать скрипты на малых выборках перед масштабированием.
Проверять существование файлов (os.path.exists()) перед операциями.
Обрабатывать исключения для предотвращения аварий.
Таким образом, глава формирует универсальный инструментарий для:
разработки ETL-пайплайнов;
• подготовки данных для машинного обучения;
• создания сервисов с интеграцией медиа и API;
• автоматизации задач в аналитике и DevOps.
Основы объектно
ориентированного
программирования
в Python
Объектно ориентированное программирование (ООП) (87] представляет со-
бой парадигму, в которой программа структурируется вокруг объектов, вза-
имодействующих посредством сообщений. В Python как в языке с динами-
ческой типизацией и гибкой семантикой ООП находит широкое применение
благодаря выразительным возможностям и адаптивности. В этой главе мы
рассмотрим ключевые концепции ООП, их реализацию в Python и практи-
ческие аспекты применения.
Основные принципы ООП
Инкапсуляция
Инкапсуляция — это принцип, позволяющий скрывать внутреннюю реализа-
цию объекта и предоставлять доступ к данным объекта только через методы. Это
достигается с помощью модификаторов доступа (например, private, protected,
public). Инкапсуляция позволяет защитить состояние объекта от неконтроли-
руемых изменений и предоставляет чистый интерфейс для взаимодействия.
Инкапсуляция нацелена на ограничение доступа к внутренним компонен-
там объекта и управление ими. Логика ее работы включает следующие шаги:
* Скрытие состояния. Использование модификаторов доступа для огра-
ничения доступа к атрибутам и методам класса. Внутреннее состояние
объекта (данные) скрыто от внешнего мира, что предотвращает слу-
чайные изменения или некорректные операции.
• Предоставление интерфейса. Определение публичных методов (гетте-
ров и сеттеров), которые позволяют контролировать доступ к закры-
тым данным. Они обеспечивают контроль над изменением атрибутов,
включая валидацию данных и обработку исключений.
♦ Обеспечение целостности данных. За счет использования инкапсуляции
можно реализовать логику, которая проверяет значения, прежде чем
они будут присвоены атрибутам объекта. Это предотвращает попадание
некорректных данных и поддерживает целостность состояния объекта.
Защита данных и свойства статуса
Python предоставляет возможность использовать двойное подчеркивание
(_ ) для создания строго защищенных атрибутов. Это не обеспечивает насто-
ящую безопасность, но усложняет доступ к атрибутам извне.
class Bar.kAccour.t:
def _init (self, balance):
self ._balance = balance # приватный атрибут
def deposit(self, amount):
self._ balance += amount
def get_oalance(self):
return self, balance
account = Bar.kAccount (ICO)
account.deposit(50)
print(account.get balance()) # Вывод: 150
# print(account.__balance) # Ошибка: AttributeError
json.duep(csv_data, jsonfile, indent-2) я Форматирование JSOH для удобства чтения
0 class BankAccount:
def ____init__(self, balance):
self.balance balance и приватный атрибут
def deposit(self, aeount):
self .__balance ♦- Mount
def get_balance(self):
return self._____balance
account • BankAccount(106)
account.deposit(50)
print(account.get_balance()) » Вывод: 150
я print(асcount-____balance) я Овмбка: Attributedrror
«. ISO
class Circle:
def ___init_(self, radius):
self,___radius • radius
^property
def radius(self):
return self.___radius
^radius.setter
def radius(self, radius):
If radius < 9:
raise ValueError("Radius cannot be negative")
self, radius « radius
Рис. 7.1
Здесь balance защищен от доступа извне, и можно взаимодействовать
с ним только через публичные методы.
Разберем каждую строку кода.
class BankAccount: — объявление класса BankAccount. Здесь создается
класс BankAccount, который представляет банковский счет.
def init (self, balance): — метод init (правильное название _init_ )
инициализирует новый объект BankAccount. Он принимает параметр balance,
который представляет собой начальный баланс счета.
self._balance = balance # приватный атрибут — приватный атрибут. Со-
здаем атрибут balance, который хранит значение баланса счета. Двойное
подчеркивание указывает на то, что он приватный, защищая его от прямого
доступа извне.
def deposit (self, amount) —метод deposit определяет операцию попол-
нения счета. Он принимает параметр amount, представляющий собой сумму,
которую необходимо добавить к балансу.
self. _balance += amount — обновление баланса. Текущий баланс попол-
няется на указанную сумму. Поскольку balance — приватный атрибут, он
доступен только внутри методов класса.
def qet_balance (self): — метод get balance предназначен для получения
текущего баланса счета. Не принимает никаких параметров
return self.__balance — возврат баланса. Метод возвращает значение
приватного атрибута___balance, позволяя получить информацию о балансе
счета, но не предоставляя возможность напрямую его изменить.
account = BankAccount (100) —создание экземпляра BankAccount. Создаем
новый объект account класса BankAccount с начальным балансом 100.
account.deposit (50) — пополнение счета. Вызываем метод deposit на объ-
екте account, добавляя 50 к его текущему балансу.
print (account.get_balance ()) * Вывод: 150 — вывод текущего баланса.
Вызываем метод get balance, который возвращает текущее значение баланса.
Программа выводит 150, что подтверждает успешное пополнение счета.
# print (account._balance) # Ошибка: AttributeError — попытка досту-
па к приватному атрибуту. Если раскомментировать эту строку, произойдет
ошибка AttributeError, указывающая на то, что мы пытаемся получить до-
ступ к защищенному атрибуту balance из внешнего контекста, что невоз-
можно из-за инкапсуляции.
Почему это пример на защиту данных и свойства статуса:
1. Приватный атрибут. Двойное подчеркивание (____) перед именем
balance делает атрибут недоступным для прямого доступа извне, обеспечи-
вая защиту данных. Это означает, что внутреннее состояние объекта (баланс)
невозможно изменить напрямую.
2. Контроль доступа. Условие доступа к атрибуту balance реализуется че-
рез публичный .метод get_balar.ce, который позволяет получать информацию
о балансе, при этом контролируя изменения с помощью метода deposit. Это
создаст интерфейс для безопасного взаимодействия с состоянием объекта.
3. Сохранение целостности. Защита данных позволяет предотвратить
несанкционированные изменения состояния объекта, поддерживая целост-
ность данных и избегая ситуаций, когда баланс мог изменяться неправомер-
ным образом.
Этот код иллюстрирует использование инкапсуляции и защиту данных
через создание приватных атрибутов в классе.
Свойства и методы
В Python вы можете использовать декораторы @property и @setter для реали-
зации инкапсуляции, что позволяет создать интерфейс для доступа к атрибу-
там, скрытым от пользователя.
class Circle:
def _init____(self, radius):
self, radius = radius
^property
def radius(self):
return self, radius
3radius.setter
def radius(self, radius):
if radius < 0:
raise ValueError("Radius cannot be negative")
self, radius = radius
circle = Circle(5)
print(circle.radius)
circle.radius = 10
print(circle.radius)
# circle.radius = -5
4 Вывод: 5
t Вывод: IC
# Ошибка: ValueError
Свойства позволяют контролировать доступ к закрытым атрибутам
и обеспечивают валидацию данных.
ас<ount.aeposit(so)
print(ac«.ount .gel_balan<,e()) я Винод: 1S3
в print(account.___balaace) я Сшибка: AttributeError
150
Q class Circle:
def ___init__(self, radius):
self.___radius - radius
^property
def radius(self):
return self.___radius
^radius.setter
def radius(se)f, radius):
if radius < 0:
raise ValueError("Radius cannot be negative')
self.__radius radius
circle - cirde(S)
print(cirrle.radius) » but ад: 5
circle.radius = J0
print(circle.radius) я выпад IO
в circle.radius = 5 я Ошибка: ValueError
••• 5
J0
class singleton:
Рис. 7.2
Разберем каждую строчку кода.
class Circle: — объявление класса Circle. Создаем класс Circle, который
представляет круг и содержит методы и атрибуты, связанные с его радиусом.
def init(self, radius):—метод init (правильное название__init_ ) ис-
пользуется для инициализации объекта Circle, принимая параметр radius,
который определяет радиус круга.
self._ radius = radius — приватный атрибут. Атрибут radius устанав-
ливается как приватный, скрытый от внешнего доступа. Это означает, что
пользователи не могут напрямую читать или изменять его значение.
^property
def radius(self):
Декоратор ^property создает метод radius, который будет работать как
свойство (геттер). Он позволяет получить значение радиуса, не обращаясь
непосредственно к приватному атрибуту.
return self, radius — возврат радиуса. Возвращаем текущее значение
приватного атрибута radius, что позволяет видеть радиус крут а.
@radius.setter
def radius(self, radius):
Декоратор (jradius. setter определяет метод radius как сеттер, что позво-
ляет устанавливать значение радиуса. Используется для контроля изменений
радиуса.
if radius < 0:
raise ValueError("Radius cannot be negative")
Проверка значения. Значение радиуса не должно быть отрицательным.
Если это так, то выбрасывается исключение ValueError с соответствующим
сообщением. Это гарантирует, что радиус всегда будет действительным.
self.____radius = radius — обновление радиуса Если значение радиуса по-
ложительное, то обновляется приватный атрибут_radius новым значением.
circle = Circle (5) —создание экземпляра Circle. Создаем новый объект
circle класса Circle с радиусом 5.
print (circle.radius) # Вывод: 5 — вывод текущего радиуса. Вызов метода
radius (гезтера) позволяет получить значение радиуса объекта circle, кото-
рое равняется 5.
circle, radius = 10 — изменение радиуса. Вызываем метод radius (сеттер)
для установки нового значения радиуса, равного 10. Поскольку это значение
положительное, атрибут__radius обновляется без ошибок.
print (circle.radius) ? Вывод: 10 — вывод текущего радиуса. После из-
менения повторно вызываем метод radius, который показывает новое значе-
ние — 10.
# circle.radius = -5 # Ошибка: ValueError — попытка установить отри-
цательный радиус. Если раскомментировать эту строку, возникнет ошибка
ValueError — радиус не может быть отрицательным. Это демонстрирует, как сет-
тер защищает объект от неверных данных и сохраняет целостность состояния
Этот код иллюстрирует использование декораторов @property и @setter
для реализации инкапсуляции, позволяя скрыть реализацию радиуса и обес-
печивая контроль доступа к нему.
Синглтоны 1/1 управляемый доступ
Инкапсуляция может поддерживаться концепцией синглтонов, когда созда-
ние экземпляра класса ограничено. Это полезно для управления совместным
доступом к ресурсам.
class Singleton:
_instance = Kone
def new (cis):
if cis.-instance is Nene:
cis.-instance = super(Singleton, cis)._new_(cis)
return cis. instance
singletonl = Sir.gleton()
singletor.2 = Singleton ()
print(singletonl is singleton2) # Вывод: True
print(circie.гaaius; ж вывод: iv
й circle.radius -5 ж Ошибка: ValueError
5
10
Q< class Singleton:
instance » None
def __new__(cis):
if cis.-instance is None:
cis.-instance » super(singleton, cis).___new__(cis)
return cis.-instance
singletoni Singleton()
singleton? Singleton()
print(singletoni is singleton?) # Вывод: True
••• True
class Temperature:
def __init__(self, Celsius):
self._celsius » Celsius
^property
def Fahrenheit(self):
return (self._celsius • 9/5) ♦ 32
^Fahrenheit.setter
def fahrenheit(self, value):
self,_celsius = (value - 3?) • 5/9
temp » Temperature(25)
Рис. 7.3
Класс Singleton гарантирует, что единственный экземпляр будет исполь-
зоваться как общая точка доступа, показывая, как инкапсуляция контроли-
рует доступ к объектам.
Инкапсуляция может поддерживаться концепцией синглтонов, при ко-
торой создается лить один экземпляр класса. Это полезно для управления
совместным доступом к ресурсам.
Разберем каждую строчку кода.
class Singleton: — объявление класса Singleton. Создаем класс Singleton
для обеспечения единственного экземпляра этого класса.
_instance = None — атрибут класса instance. Это приватный атрибут, кото-
рый используется для хранения единственного экземпляра класса Singleton.
Изначально он установлен в None.
def new (cis): — метод new отвечает за создание или получение единс-
твенного экземпляра класса. Обратите внимание, что в коде перед методом
должен быть правильный декоратор @classmethod (обычно используется для
методов, которые работают с классом, а не с экземплярами).
if cis.-instance is None: —проверка существования экземпляра. Про-
веряем, существует ли уже экземпляр класса. Если cis .-instance равно None,
значит, экземпляр еще не создан.
cis.-instance = super (Singleton, cis) .new(cls) —создание экземпляра.
Если экземпляр не существует, создается новый с помощью метода new роди-
тельского класса (необходимо использовать super ()). Результат сохраняется
в атрибуте instance.
return cis. instance — возврат единственного экземпляра. Метод воз-
вращает ссылку на экземпляр класса Singleton, созданного ранее или уже су-
ществующего.
singletonl = Singleton () —создание первого экземпляра. Создаем объект
singletonl класса Singleton. При вызове метода new возвращается единствен-
ный экземпляр.
singleton? = Singleton () —создание второго экземпляра. При создании
объекта singleton? происходит то же самое. Метод new вернет экземпляр, ко-
торый уже был создан при инициализации singletonl.
print (singletonl is singleton?) # вывод: True — проверка идентичности
экземпляров. Сравниваем ссылки на два экземпляра: singletonl и singleton?.
Поскольку оба указывают на один и тот же экземпляр, вывод будет True, что
подтверждает принцип: может быть создан только один экземпляр класса.
Почему этот пример иллюстрирует синглтон и управляемый доступ:
1. Ограниченность экземпляров. Конструкция синглтона гарантирует, что
больше одного экземпляра класса не может существовать одновременно. Это
достигается проверкой наличия созданного экземпляра и его возврата, если
он существует.
2. Управляемый доступ. Этот подход предоставляет управляемый доступ
к ресурсу, которым управляет синглтон. Все дальнейшие обращения к классу
будут ссылаться на единственный существующий экземпляр, что делает его
полезным для управления состоянием, которое должно быть общим для все-
го приложения (например, настройки конфигурации, логгирование и т. д.).
Этот код демонстрирует суть паттерна синглтон, обеспечивая уникаль-
ность экземпляра и управляемый доступ к ресурсам.
Защита состояний через свойства
Python позволяет использовать свойства (property), чтобы управлять досту-
пом к атрибутам, добавляя валидацию во время чтения или записи данными.
class Temperature:
def init (self, Celsius):
self. Celsius = Celsius
^property
def fahrenheit(self):
return (self. Celsius * 9/5) + 3?
Fahrenheit,setter
def fahrenheit(self, value):
self._celsius = (value - 32) * 5/9
temp = Temperature(25)
print(temp.fahrenheit) # Вывод: 77.0
temp.fahrenheit = 86
print(temp. Celsius) # Вывод: 30.0
return cIs.-instance
singletool - singleton()
singleton2 - Singleton()
print(singletonl is singleto«2) и Вывод: True
True
____________ Ф Ф У Э : _
Ql class Tenperature: |
def _lnit___(self, Celsius):
self.-Celsius • Celsius
^property
def fahrenheit(self):
return (self._celsius • 9/S) ♦ 32
^fahrenheit.setter
def fahrenheit(self, value):
self._celsius • (value - 32) • 5/9
teep - Temperature(25)
print(teep.fahrenheit) а Вывод: 77.6
teep. fahrenheit - St-
print (teep.-Celsius) • Вывод: 30.9
•« 77.0
3O.0
class Employee:
def _init_(self, паве, salary):
self.паве - паве • публичней атрибут
Рис. 7.4
Разберем каждую строку кода.
class Temperature — объявление класса Temperature. Создаем класс, кото-
рый представляет температуру и управляет ее значением в градусах Цельсия
и Фаренгейта.
def init (self, Celsius): — метод init (правильное название_______________init___)
используется для инициализации объекта Temperature, принимая параметр
Celsius, который устанавливает начальное значение температуры в градусах
Цельсия.
self. Celsius = Celsius — приватный атрибут Celsius инициализиру-
ется значением, переданным при создании объекта. Он хранит температуру
в градусах Цельсия, скрывая внутреннее состояние объекта.
^property
def fahrenheit(self):
Декоратор @prcperty создает метод fahrenheit, который работает как
свойство (геттер). Он позволяет получать значение температуры в Фаренгей-
тах, производя вычисление на основе внутреннего значения в Цельсиях.
return (self. Celsius * 9/5) + 32 — возврат значения в Фаренгейтах.
Вычисляем и возвращаем температуру в Фаренгейтах на основе значения
Celsius. Так мы получим корректное преобразование и доступ к информа-
ции о температуре в другой шкале.
Sfahrenheit.setter
def fahrenheit(self, value):
Декоратор 2fahrenheit.setter определяет метод fahrenheit как сеттер. Он
устанавливает значение температуры в Фаренгейтах и обновляет соответс-
твующее значение в Цельсиях.
self. Celsius = (value - 32) * 5/9 — обновление температуры в Цельси-
ях. Новое значение в Фаренгейтах преобразуется в градусы Цельсия, а при-
ватный атрибут _celsius обновляется. Так мы получим корректное взаимо-
действие между шкалами температуры.
temp = Temperature (25) —создание экземпляра Temperature. Создаем объ-
ект temp класса Temperature с начальным значением 25 градусов Цельсия.
print (temp, fahrenheit) * Вывод: 77.0 — вывод температуры в Фаренгей-
тах. Вызываем метод fahrenheit, который вычисляет и показывает текущее
значение температуры в Фаренгейтах. Результат равен 77.0, значит, преобра-
зование верно.
temp.fahrenheit = 86 — установка температуры в Фаренгейтах. Исполь-
зуем сеттер fahrenheit, чтобы установить температуру на 86 градусов по Фа-
ренгейту. Происходит автоматическое преобразование этого значения в 1 ра-
дуем Цельсия.
print (temp. Celsius) # Вывод: 30. С — вывод текущей температуры в Цель-
сиях. Выводим текущее значение приватного атрибута Celsius, который те-
перь равен 30.0, после преобразования из 86 градусов по Фаренгейту.
Почему это пример защиты состояний через свойства:
1. Контроль доступа и валидация. Свойства @property и @setter дают воз-
можность управлять доступом к приватному атрибуту Celsius. Мы можем
вносить изменения в состояние объекта только через заранее определенные
методы, добавляя слой валидации.
2. Изоляция внутреннего состояния. Приватный атрибут Celsius стано-
вится недоступным для прямого изменения извне, тем самым защищая внут-
реннее состояние от некорректных или случайных изменений. Все изменения
температуры проходят через валидирующие методы.
3. Корректное преобразование. Свойства обеспечивают правильное пре-
образование между температурными шкалами. Мы уверены, что любое вне-
шнее изменение (например, установка температуры в Фаренгейтах) приведет
к соотношению, которое сохраняет целостность данных внутри объекта.
Код иллюстрирует использование свойств для защиты состояний, благо-
даря чему контролируется доступ и изменяется внутреннее состояние объек-
та только с учетом логики, заданной в методах.
Уровни доступа
Кроме защиты данных с помощью модификаторов доступа можно исполь-
зовать соглашения о следовании именам (например, и __) для обозначения
«защищенных» и «приватных» членов класса, обеспечивая более чистую ар-
хитектуру и предполагая уровень доступа.
class Employee:
def _init__(self, name, salary):
self.name = name # публичный атрибут
self._salary = salary # "защищенный" атрибут
self.__bonuses =0 # "приватный" атрибут
def add bonus(self, bonus):
self, bonuses += bonus
def report(self):
return f'Nane:
(self, bonuses}"
{self.name}, Salary: (self,_salary}, Bonuses:
err.p = Employee ("John", 50000)
emp.add_ccnus(5000)
print(emp.report ()) # Вывод: Name: John, Salary: 5C000, Bonuses: 5000
# print(emp.__bonuses) # Ошибка: AttributeError
77-» str: name
30.0
View
0 class Employee: |
def __init__(self, name, salary):
self.name • name я публичный атрибут
self, salary salary я “та-иищепный" атрибут
self.-bonuses > 0 s "приватный" атрибут
def add_bonus(self, bonus):
self-bonuses 1» bonus
def report!self):
return f"name: {self.name). Salary: {self._salary), Bonuses: {self._ bonuses)"
нпр • Employee!"John", 50000)
emp.add bonus(5000)
print(emp.report()) я Вывод: нате: John, salary: S0000, Bonuses: 5000
# print(emp._bonuses) я Отибка; AttributeError
... Name: John, Salary: 50000, Bonuses: 5000
class A:
def method(self):
print("Metboa from A‘)
class B(A):
def metnod(self):
print(”Hethod from в")
class C(A):
def method(self):
Использование одного подчеркивания указывает на то, что атрибут защи-
щен, а два подчеркивания создают имя с «модульным» именем, что защищает
его от конфликтов.
Разберем каждую строчку кода.
class Employee — объявление класса Employee. Создаем класс Employee, кото-
рый представляет сотрудника и содержит связанные с ним атрибуты и методы.
def init(self, name, salary): — метод init (правильное название _
init__) используется для инициализации объекта Employee, принимая пара-
метры name и salary, которые устанавливают имя сотрудника и его зарплату
соответственно.
self.name = name ft публичный атрибут — создаем публичный атрибут
name, который доступен для чтения и изменения извне. Это означает, что лю-
бые пользователи класса могут свободно к нему обращаться.
self ._salary = salary # "защищенный" атрибут — создаем защищенный
атрибут _salary, который, по соглашениям о наименовании, говорит о том,
что он предназначен для использования в классе и его подклассах, но не дол-
жен быть доступен извне. Это сигнал для разработчиков, что к этому атрибу-
ту следует обращаться с осторожностью.
self, bonuses = 0 # "приватный" атрибут — создаем приватный атри-
бут ___________________bonuses, который недоступен вне класса. Двойное подчеркивание ука-
зывает на то, что этот атрибут скрыт и должен использоваться только внутри
методов класса.
def add_bonus (self, bonus): — метод addbonus добавляет бонус к приват-
ному атрибуту bonuses. Он изменяет внутреннее состояние объекта, остав-
ляя его скрытым от внешнего мира.
self, bonuses += bonus — обновление бонусов. Значение, переданное как
параметр bonus, добавляется к атрибуту bonuses. Это безопасно и подконт-
рольно, так как доступ к атрибуту осуществляется только через метод.
def report (self): — метод report генерирует отчет о состоянии сотрудни-
ка, включая его имя, зарплату и бонусы.
return f'Name: {self.name}, Salary: (self._salary}, Bonuses: (self._
bonuses}" — формирование отчета. Возвращаем строку, содержащую имя,
зарплату и бонусы сотрудника. Используем как публичный атрибут name, так
и защищенный salary и приватный bonuses.
emp = Employee ("John", 50000) —создаем объект emp класса Employee с име-
нем "John" и зарплатой 50С90.
emp.add_bonus (5000) — вызываем метод add bonus, который добавляет 50С0
к бонусам сотрудника. Изменение происходит через контролируемый метод,
что поддерживает инкапсуляцию.
print (emp.report ()) # Вывод: Name: John, Salary: 50000, Bonuses: 590; —
вызываем метод report, который возвращает строку с текущей информацией
о сотруднике, включая добавленный бонус.
# printfemp. _bonuses) # Ошибка: AttrwuteError— попытка доступа
к приватному атрибуту. Если раскомментировать эту строку, произойдет
ошибка AttnbuteError, поскольку доступ к атрибуту_bonuses извне класса
невозможен из-за его приватного состояния.
Почему это пример уровней доступа:
1. Разделение доступа. В классе Employee используются разные уровни до-
ступа: публичный (name), защищенный (_salary) и приватный ( bonuses).
Так мы градуируем уровень доступа к атрибутам в зависимости от их пред-
назначения и важности.
2. Указание намерений. Использование соглашений по наименованию дает
разработчикам четкое представление о том, как обращаться с классом и его
атрибутами. Например, атрибуты с одним подчеркиванием предназначены
для внутреннего использования, а атрибуты с двойным подчеркиванием под
полной защитой от внешнего доступа.
3. Инкапсуляция состояния. Приватные и защищенные атрибуты способс-
твуют инкапсуляции состояния объекта, что позволяет избежать случайных
изменений и поддерживать согласованность данных. Мы уверены, что внут-
ренние изменения управляются только через определенные методы (напри-
мер, add_bonus).
Этот код демонстрирует, как различные уровни доступа к членам класса
способствуют созданию четкой архитектуры и обеспечивают защиту данных,
позволяя контролировать доступ к внутреннему состоянию класса.
Наследование
Наследование позволяет создавать новый класс на основе уже существующе-
го — родительского или суперкласса. Новый класс — дочерний или произ-
водный — унаследует свойства и методы родительского, а также может до-
бавлять новые или переопределять существующие Наследование облегчает
повторное использование кода и обеспечивает иерархию классов.
Логика наследования
1. Переопределение методов. Дочерние классы могут изменять или расши-
рять функциональность методов родительского класса.
2. Множественное наследование. Python позволяет наследовать от несколь-
ких родительских классов, что помогает интегрировать различные функцио-
нальности.
3. Простота расширяемости. Наследование упрощает добавление новых
классов с минимальными изменениями в существующем коде, повышая гиб-
кость разработки и упрощая управление проектом.
Множественное наследование
Множественное наследование можег привести к «алмазной проблеме», когда
один и тот же базовый класс наследуется несколькими дочерними.
class А:
def method(self):
print("Method from A")
class B(A):
def method(self):
print("Method from B")
class C(A):
def method(self):
print("Method from C")
class D(B, C):
pass
d = D()
d.method() # Вывод: Method from В (разрешение по порядку)
* print (enp.Jwnuses) а Ошибка: Attributefcrror
наве: John, salary: 5W0O, Bonuses: 50W
---------------------------------------------------------------------------------------------------------------------- Ф Ф У I'll
ф class А: |
def method(self):
print(“Method from A")
class B(A):
def method(self):
print(“Hethod froe B")
class C(A)j
def method(self):
print(’xethod from C)
class O(B, C)s
pass
d - 0()
d.method() « Вывод: Method froe В (разрешение no порядку)
<~ Method from В
class A:
def nethod(self):
print("Method froe a")
class 9(A):
def nethod(self):
print("nethod froe в")
class C(A):
Множественное наследование позволяет комбинировать разные функци-
ональности в одном классе.
Представьте, например, что у вас есть классы А, В, С и D. Классы В и С
наследуются от А, а класс D — от В и С. Это значит, что D получает методы
и свойства, которые есть во всех остальных классах.
«Алмазная проблема»
«Алмазная проблема» возникает, когда у вас есть несколько классов, которые
наследуются от одного и того же базового класса. Если класс I) наследуется
от классов В и С, а те, в свою очередь, от А, то у D есть два пути доступа к А.
Это напоминает форму ромба или алмаза.
Если в классе А есть метод, который переопределяется в классах В и С,
возникает вопрос: какой метод вызовется, если обратиться к методу объекта
класса D? Python может запутаться, какой использовать, так как оба выгля-
дят как «обозначение» родительского класса А.
Чтобы решить эту проблему, Python использует систему под названием ме-
тод разрешения порядка (MRO). Когда вы вызываете метод у объекта, Python
определяет, в каком порядке он должен искать методы в иерархии классов.
Метод разрешения порядка устанавливает, что Python сначала ищет
в классах, от которых непосредственно наследует текущий класс, а далее вверх
по цепочке наследования. Таким образом, несмотря на путаницу, Python все
равно знает, какой метод вызвать, следуя определенному порядку.
Множественное наследование дает возможность легко комбинировать
функциональность, но нужно быть осторожным, чтобы избежать ситуации,
когда возникает неопределенность из-за «алмазной проблемы». Благодаря
MRO вызов методов предсказуем, даже когда классы имеют сложную иерар-
хию наследования.
class А:
def method(self):
print("Method from A")
class В(A):
def method(self):
print("Method from 3")
class C(A):
def method(self):
print("Method from C")
class D(B, C):
pass
class С(А):
def method(self):
print("Method from C")
class D(Bj C):
pass
d - D()
d. met hod () я Вывод: Method from В (разрешение гю порядку)
Method from в
Q class А: |
def method(self):
print("Method from a")
class B(A):
def nethod(self):
print("Method from B")
class C(A):
def method(self):
print("Method from C")
class D(B, C):
pass
class Animal:
def speak(self):
return "Animal speaks”
class Dog(Animal):
def speak(self):
Рис. 7.7
Суперклассы и метод super ()
Используя функцию super(), можно вызывать методы родительского класса
в дочерних классах, что упрощает код и делает его более читаемым.
class Animal:
def speak(self):
return "Animal speaks"
class Dog(Animal):
def speak(self):
return super().speak() + ": Woof!"
dog = Dog()
print(dog.speak()) f Вывод: Animal speaks: Woof!
super () используется для получения доступа к методу speak() родитель-
ского класса Animal.
Поговорим о функции super () и о том, как она помогает в работе с класса-
ми и наследованием в Python.
Когда у нас есть классы, которые наследуют свойства и методы других
классов, иногда нам нужно использовать или расширить поведение роди-
тельского класса в дочернем. На помощь приходит функция super ().
раза
С class Animal:
def speak(self):
return "Animal speaks"
class Dog(Animal):
def speak(self):
return super ().spe<ik() + ” Woofl"
dog ^8-)
print(dog.speak()) А вывод: Animal speaks: Woofl
— Animal speaks: woofl
class shape:
del area(self):
raise MotHplementedfrrorfsubclasses must implement this mernod.")
class Rectangle(Shape):
del __init__(self, width, height):
self.width • width
self.height - height
def area(self):
return self.width self-height
class Lircle(shape):
def init____(self, radius):
self.raaius - raaius
def area(self):
from math import pi
return pl * (self.raaius •• 2)
Рис. 7.8
Она позволяет обращаться к методам родительского класса из дочернего.
Эт о особенно полезно, когда дочерний класс переопределяет методы родитель-
ского, но вам все равно нужно вызвать оригинальную версию этого метода.
Разберем каждую строку этого кода.
class Animal: — создаем базовый класс Animal. Классы в Python исполь-
зуются для создания объектов (экземпляров), которые имеют собственные
свойства и методы.
def speak(self):
return "Animal speaks"
Внутри класса Animal определяем метод speak. Он возвращает строку "Animal
speaks". Метод доступен для всех классов, которые наследуют от Animal. В этом
контексте его можно считать базовым поведением для всех животных.
class Dog(Animal): — создаем класс Dog, который наследует от класса
Animal. Это означает, что класс Dog получает все методы, которые определены
в классе Animal, включая метод speak.
def speak(self):
return super().speak() + ": Wcof!"
Переопределение метода speak. В классе Dog мы переопределяем метод
speak. Вместо того чтобы просто возвращать строку, он вызывает родитель-
ский метод speak с помощью super (), который возвращает "Animal speaks".
Затем добавляем к этому результату строку ": Wcof!", что представляет звук,
который издает собака. Таким образом, метод speak класса Dog сочетает пове-
дение родительского класса с новым, специфичным для класса Dog.
dog = Dog () — создаем экземпляр класса Dog и сохраняем его в переменную
dog. Теперь у нас есть объект dog, который представляет конкретную собаку.
print (dog. speak()) # Вывод: Animal speaks: Woof! —вызываем метод
speak на объекте dog. Так как метод был переопределен в классе Dog, выполня-
ется его версия, которая сначала вызывает родительский метод speak, чтобы
получить строку "Animal speaks", а затем добавляет ": Woof!". В итоге вывод
будет "Animal speaks: Woof!".
Каждая строчка этого кода выполняет свою функцию: от определения
базового класса и его метода до создания конкретного класса, который рас-
ширяет и изменяет поведение родительского метода, обеспечивая чистоту
и расширяемость кода.
Полиморфное наследование и изменение поведения
Наследование можно использовать для создания архитектур, где дочерние
классы могут не только переопределять методы, но и изменять логику вы-
полнения в родительских классах.
class Shape:
def area(self):
raise NotlmplementedError("Subclasses must implement this
method.")
class Rectangle(Shape):
def init (self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
class Circle(Shape):
def init_ (self, radius):
self.radius = radius
def area (self):
from math import pi
return pi * (self.radius ** 2)
shapes = (Rectangle(5, 10), Circle(7)]
tctaiarea = sum(shape.area() for shape in shapes)
print(tctal_area) # Выводит плошадь всех фигур
Animal speaks: woofi
0 class Shape:
def area(self):
raise NotImplementedError("$ubclasses must implement this method.")
class Rcctanglo(Shape):
def init____(self, width, height):
self.width • width
self.height height
def area(self):
return self.width w self.height
class Circle(Shape):
def ___init__(self, radius):
self.radius * radius
def area(self):
from math import pi
return pi • (self.radius •• 2)
shapes [Rectangle(5, 10), circle(7)]
total area • sum(shape.area() for shape in shapes)
print(total area) 9 Выводит площадь всех фигур
... 203.93804002589985
class ListUrapper:
def __init__(self, wrappedlist):
self.wrapped_list - wrapped_list
def add(self, item):
Рис. 7.9
Можно добавить новые фигуры, создавая дочерние классы, переопреде-
ляя метод area ().
Наследование в объектно ориентированном программировании — это
один из ключевых принципов, который позволяет создавать иерархии клас-
сов, где дочерние классы могут наследовать свойства и методы родитель-
ских. Это позволяет эффективно повторно использовать код и организовы-
вать его.
Создавая дочерний класс, вы можете не только переопределить методы
родительского класса, но и изменить логику их выполнения. Можно взять
существующую функциональность и модифицировать ее так, чтобы она луч-
ше соответствовала нуждам дочернего класса. Например, изменить способ
обработки данных, добавить дополнительные проверки или создать более
сложные взаимодействия.
Наследование дает гибкость. Можно использовать базовые классы как
основу и адаптировать их под конкретные требования, создавая более спе-
циализированные версии. Это упрощает разработку и позволяет легко уп-
равлять изменениями. Если нужно внести изменения в общую логику, вы мо-
жете сделать это в родительском классе, и все дочерние классы сразу получат
новую логику.
Кроме того, такая структура способствует улучшению читаемости кода,
так как связь между классами становится более понятной. Разработчики
быстрее поймут, как функционируют и взаимодействуют классы. Использо-
вание наследования для изменения логики выполнения в родительских клас-
сах делает код более модульным и управляемым.
Давайте разберем каждую строчку этого кода.
class Shape: — создаем базовый класс Shape, который будет служить ос-
новой для других классов фигур. Этот класс задает общую структуру для всех
фигур, которые от него наследуют.
def area(self):
raise NotlmplementedError("Subclasses must implement this
method.")
Внутри класса Shape определяем метод area. Он предназначен для вычис-
ления площади фигуры, но не реализован. Если кто-то попытается вызвать
его напрямую из класса Shape, то он вызовет исключение NotlmplementedError.
Это сигнализирует о том, что любой дочерний класс должен реализовать этот
метод, используя свою собственную логику.
class Rectangle (Shape): — создаем класс Rectangle, который наследует от
класса Shape. Это означает, что Rectangle имеет доступ к методам и свойс-
твам, определенным в Shape, а также может реализовать свои собственные.
def init(self, width, height):
self.width = width
self.height = height
Определяем метод init (правильно:___init__), который должен инициа-
лизировать объект с заданной шириной и высотой. В текущем коде этот ме-
тод не будет вызываться автоматически при создании объекта.
def area (self):
return self.width * self.height
Переопределение метода area. Реализуем метод area, который рассчиты-
вает площадь прямоугольника как произведение ширины на высоту. Это поз-
воляет объектам Rectangle вычислять собственную площадь.
class Circle (Shape) : —создаем класс Circle, который наследует от класса
Shape аналогично классу Rectangle.
def init (self, radius):
self.radius = radius
В классе Circle определяем метод init (правильно: _init _), который
инициализирует объект с радиусом.
def area(self):
from math import pi
return pi * (self.radius ** 2)
Переопределение метода area. Реализуем метод area, который вычисля-
ет площадь круга по формуле л * радиус2. Обратите внимание, что для ис-
пользования константы л мы импортируем ее из модуля math. Это позволяет
объектам Circle также вычислять свою площадь.
shapes = [Rectangle (5, 10), Circle (7) ]—создаем список shapes, который
содержит экземпляры классов Rectangle и Circle. Этот код вызовет ошибку,
так как вместо init должно быть__init__.
total area = sum (shape.area () for shape in shapes) —вычисляем общую
площадь всех фигур. Используем генераторное выражение, чтобы пройтись
по каждому объекту в списке shapes и вызвать метод area () для каждого, сум-
мируя полученные значения.
print (total_area) # Выводит площадь всех фигур — производим вывод об-
щей площади всех фигур на экран. Из-за ошибок в методах инициализации
код не сможет выполнить свою задачу без исправлений.
Этот код демонстрирует, как можно использовать наследование и перео-
пределение методов для создания архитектуры, в которой различные формы
могут вычислять свою площадь.
Класс-обертка (wrapper class)
Рассмотрим, как использовать наследование для создания класса-обертки,
который добавляет функциональность к существующим классам, не изме-
няя их.
class ListWrapper:
def init (self, wrapped_lrst):
self.wrapped_list = wrapped_list
def add(self, item):
self.wrapped_list.append(item)
def get(self, index):
return self.wrapped_list[index]
@classmethod
def create_with_range(cis, start, end):
return cis(list(range(start, end)))
# Использование
my_list = ListWrapper.create_with_range(0, 5)
my_list.add(5)
print(mylist.wrapped list) # Вывод: [0, 1, 2, 3, 4, 5]
203.93804002‘j8998S
О class listwrapper:
def _init___(self, wrappedlist):
self.wrappediist » wrappedlist
def add(self, item):
seif.wrapped_list.append)item)
def f*et(self, index):
return self.wrapped,]istflndex]
0classmetbod
def create_with_range(cls, start, end):
return cls(list(range(start, end)))
о использование
rnylist - Listwrapper.create with. rangeiP, 5)
my_list.add(S)
print(my list.wrapped list) я Ьынод. [e, 1, 2, 3, 4, S]
— f0, 1, 2, 3, 4, 5)
from typing import list, lypeVar
T • TypeVar(’T')
def add_to_list(item: T, item_list: list[T]) > list[T]:
item_]i st.append(item)
return item_list
Рис. 7.10
Класс ListWrapper добавляет функциональность к базовому списку, оста-
ваясь при этом ненарушенным.
Разберем каждую строчку кода.
class ListWrapper: — создаем класс ListWrapper, который будет служить
оберткой для стандартных списков Python, добавляя им функциональность.
def init (self, wrapped_list): —метод init (_init ) используется для
инициализации нового объекта ListWrapper, принимая параметр wrapped
list, — список, который будет обернут.
self .wrapped_list = wrappea list — приватный атрибут. Объект wrapped
list сохраняется как атрибут экземпляра self .wrappedlist. Это дает доступ
к исходному списку внутри класса.
def add (self, item): — метод add предназначен для добавления элемен-
та item в обернутый список. Он инкапсулирует логику добавления элемента,
предоставляя внешний интерфейс для добавления.
self .wrapped_list.append(item) — вызываем метод append на списке self.
wrapped_list, чтобы добавить элемент item. Этот шаг демонстрирует, как
класс-обертка использует функциональность исходного списка,
def get (self, index): — метод get предназначен для получения элемента
из обернутого списка по указанному индексу.
return self.wrapped_list[index] — возвращаем элемент из списка self.
wrapped_list по заданному индексу. Это обеспечивает доступ к элементам
списка через обертку.
@classir.ethod
def createwithrange(cis, start, end):
Декоратор Gclassmethod определяет метод create with_range как метод
класса, который может вызываться непосредственно на классе, а не на его
экземплярах. Он принимает параметры start и епа для создания списка.
return cis (list (rar.ge (start, end))) — создаем и возвращаем новый эк-
земпляр класса ListWrapper, который инициализируется списком, созданным
из диапазона чисел от start до end (не включая end). Позволяет удобно созда-
вать обертки с заданным диапазоном.
? Использование
my list = ListWrapper.create_with_range(0, 5)
Вызываем метод create with_range,чтобы создать новый объекгту list —
обертку для списка [0, 1, 2, 3, 4].
ir.y_list.ada(5) — вызываем метод add, чтобы добавить элемент 5 в обер-
нутый список. Это показывает, как использовать функциональность обертки
для работы с исходным списком.
print(my_list.wrapped_list) I Вывод: [0, 1, 2, 3, 4, 5]—выводим со-
держимое wrapped list, которое теперь включает элементы [0, 1, 2, 3, 4,
5], что подтверждает, что элемент был добавлен успешно.
Почему это пример класса-обертки:
1. Инкапсуляция функциональности. Класс ListWrapper служит оберткой,
добавляя функциональность к обычному списку. Он инкапсулирует опера-
ции добавления и получения элементов, позволяя взаимодействовать с ос-
новным списком через более чистый интерфейс.
2. Расширение существующего класса. Класс -обертка использует стандар-
тный список как компонент, не изменяя его внутреннее состояние или струк-
туру. Это позволяет добавлять дополнительные функции без необходимости
модифицировать базовый класс.
3. Гибкость. Обертка легко расширяет функциональность для работы со
списком, например можно добавить дополнительные методы для сортиров-
ки, фильтрации и т. д., сохраняя базовый функционал неизменным.
Код иллюстрирует применение класса-обертки, который добавляет функ-
циональность к существующему классу, поддерживая его неизменным и пре-
доставляя более удобный интерфейс.
Полиморфизм
Полиморфизм обрабатывает объекты разных классов через общие интер-
фейсы. Он достигается двумя способами: через переопределение методов
(override) и перегрузку методов (overload). С помощью полиморфизма, на-
пример, можно использовать один и тот же метод для разных объектов, и про-
грамма ведет себя определенным образом в зависимости от класса объекта.
Полиморфизм позволяет использовать объекты разных классов через
единый интерфейс, упрощая код и повышая его универсальность.
Ключевые аспекты:
• Единый интерфейс. Объекты, наследуемые от одного родительского
класса, реализуют его методы по-разному, обеспечивая герметичность
интерфейса.
• Динамическая привязка позволяет вызывать соответствующие методы
в зависимости от типа объекта во время выполнения.
• Переопределение и перегрузка. Дочерние классы могут переопределять
методы родителя. В Python пере!рузку можно имитировать с помощью
аргументов по умолчанию или *args и **kwargs.
• Упрощение кода. Полиморфизм снижает количество условных опера-
торов и уменьшает жесткую связность, что приводит к более чистому
поддерживаемому коду и легкости добавления новых классов.
Сложный полиморфизм с использованием дженериков
Параметрические функции и классы создают обобщенные методы, кото-
рые работают с различными типами данных.
from typing import List, TypeVar
T = TypeVar('T')
def add_to_list(item: T, item_list: List[T]) -> List[T]:
item_list.append(item)
return item_list
numbers = ada_tc_list(5, [])
strings = add_to_list("hello", [])
print(numbers) # Зывод: [5]
print (strings) If Зывод: ['hello']
Полиморфизм позволяет add to_list работать как с числами, так и со
строками, демонстрируя гибкость и мощь типизации.
Разберем каждую строку кода.
from typing import List, TypeVar
Из модуля typing импортируем типы List и TypeVar. List используется для
аннотирования списков, a TypeVar позволяет создавать обобщенные типы.
Т = TypeVar (<Т>)
С помощью TypeVar создаем обобщенный тип Т, который может иредстав-
ля гь любой тип. Это позволяет функции работать с разными типами данных.
def add_to list(item: T, item_list: List[T]) -> List[T]:
mylist - Listwrapper.create_with_range(o, 5)
ey_li$t.add(5)
priat(eylist.wrapped.li$t) * Вывод: (в, 1, 2, Э, 4, 5]
— [0, 1, 2, 3, 4, 5)
--------------------------------------------------------------------------------------------------------------------Ф 4- V 0 :
(Q from typing import List, Typevar |
т • Typevar('T’)
def add_to_list(item: T, item_list: List[T]) -> List(T):
item_list.append(item)
return item^list
numbers « udd_to_list(5, (])
strings - add to^isti"hollo", (])
print(ouabers) я вывод: (5]
print(strings) я вывод: ('hello']
- [5]
['hello']
class Bird:
def fly(self):
return "Flying"
class Airplane:
def fly(self):
return "Flyirqj high"
def letsfly(flyable):
Рис. 7.11
Определяем функцию add_to_list, которая принимает элемент item типа Т
и список item List, состоящий из элементов того же типа Т. Функция возвра-
щает список того же типа.
item_list.append(item)
Добавляем элемент item в список item_list. Это позволяет обрабатывать
различные типы данных, сохраняя типовую безопасность.
return itemjlist
Возвращаем обновленный список item l ist, который теперь содержит но-
вый элемент.
numbers = add_to_list(5, (j)
Вызываем функцию add_to_list, передавая чисто 5 и пустой список. Ре-
зультатом будет список, содержащий одно число [5], который сохраняется
в переменной numbers.
strings = add_to_list("hello", [])
Вызываем ту же функцию, но со строкой "hello" и пустым списком. Ре-
зультатом будет список со строкой ['hello'], который сохраняется в пере-
менной strings.
print(numoers) # Вывод: [5]
Выводим содержимое переменной numbers, что показывает, что функция
правильно добавила элемент в список.
print(strings) # Вывод: ['hello']
Выводим содержимое переменной strings, что подтверждает коррект-
ность работы функции с элементами другого типа.
# Использование
ir.y_list = ListWrapper.create_with_range (0, 5)
my list.add(5)
print(my list.wrappedlist) # Вывод: [0, 1, 2, 3, 4, 5]
Здесь вы увидите пример использования списка с классом-оберткой
(ListWrapper), чтобы продемонстрировать добавление элемента в обернутый
список.
Почему это пример использования дженериков.
1. Обобщенные функции. Функция add to list использует параметричес-
кий тип Т, что позволяет создавать функцию, которая может работать как
с числами, так и со строками или другими типами, не задавая конкретный
тип данных заранее.
2. Типовая безопасность. Использование TypeVar и аннотаций типов га-
рантирует, что элементы, добавляемые в список, соответствуют его типу. Это
предотвращает возможные ошибки на этапе выполнения
3. Универсальность. Благодаря дженерикам функции и классы становятся
более универсальными, позволяя легко применять одну и ту же логику для
работы с различными типами данных. Это упрощает и делает код более чис-
тым и эффективным.
Код иллюстрирует использование дженериков для создания параметри-
ческих функций, которые могут работать с различными типами данных, со-
храняя при этом типовую безопасность.
Полиморфизм через интерфейсы и duck typing
Python использует подход, известный как duck typing, который подразумева-
ет определение типа объекта по его поведению, а не по явному указанию типа.
class Bird:
def fly(self):
return "Flying"
class Airplane:
def fly(self):
return "Flying high"
def lets fly(flyable):
print(flyable.fly())
bird = BirdO
airplane = Airplane()
lets fly(bird) # Вывод: Flying
lets fly(airplane) # Вывод: Flying high
print(strings) It Вывод: [‘hello’)
(SJ
( hollo']
r' ..................... — “
© class Bird:
def fly(self):
return "Flying"
class Airplane:
def fly(self):
return "Flying high"
def lets_fly(flyable):
print(flyable.fly())
bird - Bird()
airplane AirplaneQ
lets_fly(bird) # Вывод: Flying
lets_fly(airplane) * вывод: Flying high
... Hying
Flying nigh
I
class Strategy:
def execute(self, a, b):
pass
class Add(Strategy):
def execute(self, a, b):
return a + b
class Subtract(Strategy):
Рис. 7.12
Функция lets_fly принимает любой объект, у которого есть метод f 1у (),
демонстрируя полиморфное поведение без необходимости явного указания
типа.
Разберем каждую строчку кода.
class Bird:
Создаем класс Bird, который представляет птицу и определяет ее поведе-
ние,
def fly(self):
Метод fly описывает поведение птицы, которое возвращает строку
"Flying", обозначающую способность птицы летать.
class Airplane:
Создаем класс Airplane, который представляет самолет и также определя-
ет его поведение,
def fly(self):
Метод fly определяет поведение самолета. Он возвращает строку "Flying
high", указывая, что самолет тоже может летать.
def lets_fly(flyable):
Функция lets_f1у принимает один параметр flyable, который может пред-
ставлять любой объект, обладающий методом fly. Это демонстрирует принцип
duck typing, где важно только наличие метода, а не конкретный тип объекта.
orint(flyable.fly())
Вызываем метод fly на переданном объекте flyable. Поскольку оба класса
(Bird и Airplane) реализуют этот метод, они используются без проверки типов.
bird = Bird () —создаем объект bird класса Bird.
airplane = Airplane () —создаем объект airplane класса Airplane.
lets_fly(bird) # Вывод: Flying — вызываем функцию lete fly, переда-
вая ей объект bird. Вызываем метод fly класса Bird и выводим "Flying".
lets_fly(airplane) К Вывсд: Flying high — снова вызываем функцию
lets fly, но теперь передаем объект airplane. Вызываем метод fly класса
Airplane и выводим "Flying high".
Почему это пример интерфейсов и duck typing:
1. Интерфейсы через метод. Оба класса (Bird и Airplane) реализуют один
и тот же метод fly. Мы получаем неявный интерфейс, который определяется
по имени метода, а не по типу объекта.
2. Deck typing. Используя lets_fly, мы видим, что важен не конкретный
тип (птица или самолет), а наличие метода fly. В этом суть duck typing — ес-
ли объект летает и издает звук, подобно птице, мы можем с ним работать как
с птицей независимо от фактического типа.
3. Универсальность кода. Код функции lets_fly работает как с классом
Bird, так и с классом Airplane, что демонстрирует гибкость и универсаль-
ность, позволяя добавлять новые летающие объекты без изменения логики
в функции.
Код иллюстрирует концепции интерфейсов и duck typing в Python, пока-
зывая, как можно работать с разными типами объектов, основываясь на их
поведении.
Паттерн «Стратегия»
Полиморфизм также может применяться для реализации паттерна «Страте-
гия», что позволяет выбирать алгоритмы динамически во время выполнения.
class Strategy:
def executelself, a, b):
pass
class Add(Strategy):
def execute(seif, a, b):
return a + b
class Subtract(Strategy):
def execute(self, a, b):
return a - b
class Context:
def _ init_ (self, strategy: Strategy):
self.strategy = strategy
def executestrategy(self, a, b):
return self.strategy.execute(a, b)
context = Context(Add())
print(context.execute strategy(5, 3)) # Вывод: 8
context.strategy = Subtract()
print(context.execute_strategy(5, 3)) # Вывод: 2
В этом примере контекст использует полиморфные стратегии для выпол-
нения операций, на лету меняя поведение через обратные связи.
Разберем каждую строчку кода.
class Strategy: — создаем абстрактный класс Strategy, который опреде-
ляет интерфейс для всех стратегий. Он содержит метод execute, который дол-
жен реализовываться в подклассах.
def execute(self, a, b):
pass
Метод execute пока не реализован (принимает на вход параметры а и Ь),
но должен быть определен в подклассах, представляя конкретную стратегию
выполнения операции.
class Add(Strategy): — создаем класс Add, который наследует от Strategy.
Он реализует стратегию сложения.
def execute(self, a, b):
return a + b
Реализуем логику сложения двух чисел а и b и возвращаем их сумму.
class Subtract (Strategy): — создаем класс Subtract, который также на-
следует от Strategy. Этот класс реализует стратегию вычитания.
def execute(self, a, b):
return a - b
Метод execute реализует логику вычитания и возвращает разность чисел а и Ь.
class Context: — создаем класс Context, который использует стратегию
для выполнения определенных операций.
def init (self, strategy: Strategy): —метод ir.it инициализирует объ-
ект Context, принимая стратегию (strategy), которая должна реализовывать
интерфейс Strategy.
self .strategy = strategy — переданную стратегию сохраняем в атрибуте
self .strategy, чтобы использовать при выполнении операций.
def execute_strategy (self, a, b) : —метод execute strategy принимает
два числа а и b и делегирует выполнение операции текущей стратегии.
return self. strategy. execute (a, b) — вызываем метод execute на страте-
гии, передавая в него два числа. Он вернет результат выполнения соответс-
твующей операции (сложение или вычитание).
context = Context (Add ()) — создаем объект context класса Context и в ка-
честве стратегии передаем Add, что означает, что по умолчанию будет выпол-
нено сложение.
print (context, execute strategy(5, 3)) # Зывод: 8 — вызываем метод
execute strategy, который возвращает результат сложения, и выводим "8".
context, strategy = Subtract () —в этой строке стратегия в объекте context
изменяется на Subtract. Теперь context будет выполнять вычитание.
print (context, execute strategy(5, 3)) # Вывод:—снова вызываем метод
execute_strategy, который теперь возвращает результат вычитания. Выво-
дится "2".
Почему это пример паттерна «Стратегия»:
1. Определение интерфейса. Класс Strategy задает интерфейс для всех
стратегий, в то время как Add и Subtract предоставляют конкретные реали-
зации. Это основная идея паттерна «Стратегия» — иметь возможность заме-
нять алгоритмы в зависимости от контекста.
2. Динамическая замена алгоритмов. Паттерн позволяет динамически из-
менять поведение объекта. Мы сначала используем стратегию сложения, а за-
тем сменяем ее на стратегию вычитания, не меняя клиентский код.
3. Изолирование алгоритмов. Каждая стратегия изолирована в своем клас-
се, что облегчает добавление новых стратегий. Это способствует принципам
SOLID, например принципу единственной ответственности.
Код иллюстрирует применение паттерна «Стратегия» с помощью поли-
морфизма, позволяя выбирать и заменять алгоритмы динамического выпол-
нения операций.
Интерфейсы через duck typing
В Python нет строгих интерфейсов, но можно использовать концепцию duck
typing, где сам тип объекта определяется не через его класс, а через методы,
которые он поддерживает.
class Duck:
def quack(self):
return "Quack!"
class Dog:
def quack(self):
return "Woof, I can quack too!"
def make_it_quack(animal):
return animal.quack()
duck = Duck()
deg = Dog ()
printfmake it quack(duck)) # Вывод: Quack!
print(make it_quack(dog)) # Вывод: Woof, I can quack too!
Функция make it quack может принимать любые объекты, которые реали-
зуют метод quack, демонстрируя гибкость полиморфизма.
class Duck: — создаем класс Duck, который представляет утку. Он будет
иметь свои собственные методы, включая метод quack.
def quack (self): — метод quack описывает поведение утки. Он будет воз-
вращать строку "Quack!" при вызове.
return "Quack!" — возвращаем строку "Quack!", имитируя звук, который
издает утка.
class Dog: — создаем класс Dog, который представляет собаку. Его будет
иметь и метод quack, даже если он не соответствует типичному поведению
этой категории животных.
def quack (self): — определяем метод quack для класса Dog, который также
возвращает строку, но она отражает особенность этой собаки.
____________________________________________ 1 + Код + Тист L
0 class Duck:
def quack(self):
return "QuackI"
class Dog:
def quack(self):
return "woof, I can quack tool”
def »ake_ it. qu«k(ani«al):
return ani®al.qu<Kk()
duck - Duck()
<k>g - oog()
print(aakeitquack^diKk)) • Вывод: Quack!
print(eakeit_quack,dog)) я вывод: Woof, I can quack too!
Quack I
Woof, I can quack too!
Ф 4- У В 4 —
free typing ieport Typevar, Generic
T • TypeVar(’T')
class Container(Geoeric(T]):
def _init_(self):
self, item - []
def add(self, item T);
self .item. append(ite«)
def get(self) > T:
return self.ite«s[O]
в использование с различными типами
Рис. 7.13
return "Woof, I can quack too!" — возвращаем строку "Woof, I can quack
too!", указывая, что эта собака может крякать (на самом деле она лает и шу-
тит, сравнивая себя с уткой).
def make it_quack(animal): — функция make_ it quack принимает один па-
раметр animal, который может быть любым объектом, реализующим .метод
quack. Это duck typing, где важно только наличие метода, а не конкретный
тип объекта.
return animal.quack() — вызываем метод quack на переданном объекте
animal и возвращаем результат.
duck = Duck () —создаем объект duck класса Duck, который представляет
утку.
dog = Dog () — создаем объект dog класса Dog, который представляет со-
баку.
print (make_it_quack(duck)) # Вывод: Quack! — передаем объект duck
в функцию make_it_quack, которая вызывает метод quack для Duck и выводит
"Quack!".
print(make_it_quack(deg)) I Вывод: Woof, I can quack too!—передаем
объект dog в функцию make_it_quack. Вызываем метод quack для Dog и выво-
дим "Woof, I can quack too!".
Код демонстрирует принципы полиморфизма и duck typing в Python, где
метод make_ it_quack может принимать различные объекты, которые реали-
зуют метод quack, независимо от их конкретного типа. Это позволяет писать
более универсальные и гибкие программы, не заботясь о том, какой класс ис-
пользуется.
Обобщенные функции и классы
Обобщенные классы позволяют создавать более универсальные структуры,
которые работают с любыми типами данных, обеспечивая чистоту и читае-
мость кода.
from typing impert TypeVar, Generic
T = TypeVar('T')
class Container(Generic[T]):
def ______init__(self):
self.items = []
def add(self, item: T):
self.items.append(item)
def get(self) -> T:
return self.items(0]
# Использование с различными типами
int_container = Container[int]()
int_container.aad(1)
string_container = Container[str]()
string container.add("hello")
print(int_container.get()) f Вывод: 1
print(stringcontainer.get()) # Вывод: hello
Разберем каждую строчку кода.
from typing import TypeVar, Generic — из модуля typing импортируем
TypeVar, нужный для создания параметрических типов, и Generic, позволяю-
щий создать обобщенный класс.
Т = TypeVar (<Т>) —с помощью TypeVar создаем параметр 7, который пред-
ставляет любой тип данных, благодаря чему работает класс Container.
class Container (Generic [Т]): — создаем класс Container, который насле-
дуется от Generic [Т]. Так он принимает параметр типа Т, что делает его обоб-
щенным.
def init(self):
self.items = []
Метод init инициализирует экземпляр класса, создавая пустой список
self. items, который хранит добавленные элементы. (Правильно _init .)
def add (self, item: T):—метод ada принимает элемент item типа T
и позволяет добавлять его в контейнер.
woof, I сап quack tool
Г---------------------------------------------------------------------------------------------------------------------Ф Ф У 0 :
01 free typing ii rt TypeVar, Generic
I Typevar(’T’)
class Container(Generic[T]):
def ___init__(self):
self, item - ()
def add(self> itea: T):
self .item, appendf It e«)
def get(self) •> T:
return self.ite«s[O]
• Использование с различны** типами
int_container Container[intJ()
int_container.add(1)
$tring_eontainer container[str]()
string^container.add("hello")
print(int_container.get()) в Вывод: 1
prlnt(string-container.get()) « Вывод; hello
••• 1
hello
froe abc ABC, abstractmethod
class Animal(abc):
pabst racteet hod
def sound(self):
pass
class Dog(Anieal):
Рис. 7.14
self .items, append (item) — добавляем элемент item в список self.items,
позволяя контейнеру хранить данные.
def get (self) -> T: —метод get возвращает первый элемент из контейне-
ра и указывает, что он будет возвращен типом Т.
return self .items [0] — возвращаем первый элемент списка self, items.
Важно учитывать, что на данный момент не предусмотрена проверка на пус-
тоту списка.
f Использование с различными типами
int_container = Container[int]()
Создаем объект int_container класса Container, который хранит элементы
типа int.
int_container.add (1) — добавляем в контейнер целое число 1.
stringcontainer = Container[str]() — создаем объект string container
класса Container, который хранит элементы типа str.
string_container. add ("hello") — добавляем в контейнер строку "hello".
print(int_container.get ()) ff Вывод: 1 — вызываем метод get у int
container, который возвращает 1, и выводим на экран.
print(string_container.get()) * Вывод: hello — вызываем метод get
у string container, который возвращает строку "hello", и выводим на экран.
Почему это пример обобщенных функций и классов:
1. Параметрический тип. Класс Container использует параметр Т, что поз-
воляет создавать контейнеры для любых типов данных и работать с обоб-
щенными классами.
2. Гибкость и повторное использование. Этот класс можно использовать
повторно для хранения объектов различных типов без необходимости пи-
сать от дельные классы для каждого. Это делает код более гибким и легким.
3. Типовая безопасность. Использование TypeVar обеспечивает статичес-
кую типизацию, что помогает избежать ошибок, связанных с неправильны-
ми типами данных при добавлении и получении элементов.
Код иллюстрирует применение обобщенных функций и классов в Python,
показывая, как создавать универсальные структуры данных, которые рабо-
тают с различными типами.
Абстракция
Абстракция в ООП позволяет сосредоточиться на ключевых характерис-
тиках объекта, игнорируя несущественные детали. Это позволяет обратить
внимание на специфических аспектах объекта при проектировании системы.
В ООП она реализуется через абстрактные классы и интерфейсы, которые
определяют методы, но не содержат их конкретных реализаций.
Логика работы абстракции:
• Определение интерфейса. Создание абстрактных классов или интер-
фейсов, которые задают набор методов для реализации в наследующих
классах, обеспечивая единообразие функциональности.
• Скрытие данных. Доступ к сложным деталям реализации ограничен,
оставлены только важные методы и атрибуты, что упрощает взаимо-
действие с объектами.
• Создание иерархии. Упрощение структуры классов путем создания ба-
зовых и производных классов, например Транспортное средство как ро-
дительский класс для Автомобиль и Велосипед, который наследует общие
характеристики, такие как движение () и остановиться().
В Python нет интерфейсов, как, например, в Java, где интерфейс — это от-
дельный тип, который определяет, какие методы должны реализовать клас-
сы. Но в Python все равно можно добиться похожего результата с помощью
абстрактных классов из модуля abc.
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def sound(self):
pass
class Dog(Animal):
def sound(self):
return "Woof!"
class Cat(Animal):
def sound(self):
return "Meow!"
# Использование
animals = [DogO, Cat () ]
for animal in animals:
print(animal.sound())
scring_conrainer .эо(ц neuo j
print(int_containcr.get()) • Вывод: 1
print(string_contaif»cr.gct()) # Вывод: hollo
1
hello
----------------------------------------------------------------------------------------------------------------------ф Ф ® .
© from abc iiex“-t ABC, abstract method
class Anieal(ABC):
£abstractmethod
def sound(self):
pass
class Dog(Aninal):
def sound(self):
return ’woof I"
class Cat(Anieal):
def sound(self):
return “MeowI"
s использование
animals [Dog(), Cat()]
for animal in animals:
print(animal.sound(j)
... woof I
Meow!
class Engine:
def start(self):
Рис. 7.15
Здесь Animal — это абстрактный класс, a Dog и Cat реализуют его методы.
Абстрактный класс — это своего рода шаблон. Он не может использовать-
ся для создания объектов напрямую. Вместо этого, создавая абстрактный
класс, вы можете указать методы, которые должны быть реализованы в клас-
се-наследнике. Они помечаются специальным декоратором Gabstractmethod,
что как бы говорит: любой класс, который наследует этот абстрактный класс,
обязательно должен реализовать этот метод.
Таким образом, можно создать основной класс, который задает интер-
фейс, а потом и конкретные классы, которые реализуют нужные методы. На-
пример, если у вас есть абстрактный класс "Животное" с методом издать звук,
то классы "Собака" и "Кошка" должны определить, как именно они издают
звук, иначе их невозможно создать.
Этим способом вы обеспечиваете строгость и четкость: любой класс, ос-
нованный на абстрактном классе, следует определенному контракту и реали-
зует все необходимые методы. В результате ваш код становится более органи-
зованным и предсказуемым.
from abc import ABC, abstractmethod — импортируем класс ABC и деко-
ратор abstractmethod из модуля abc. АВС позволяет создавать абстрактные
классы, a abstractmethod используется для пометки методов, которые должны
быть реализованы в дочерних классах.
class Animal (АВС): —создаем абст рактный класс с именем Animal, который
наследует от АВС. Значит, Animal будет служить шаблоном для других классов
и не может быть инстанцирован (нельзя создать объект класса Animal).
Sabstractmethod
def sound(self):
pass
Определяем абстрактный метод sound, помечая его декоратором @
abstractmethod. Этот метод не имеет реализации (тело метода пустое с ис-
пользованием pass), он просто объявляет, что любой класс, наследующий
Animal, должен реализовать этот метод.
class Dog (Animal): — создаем класс Dog, который наследует от абстракт-
ного класса Animal. Теперь Dog обязан определить метод sound.
def sound(self):
return "Woof!"
В классе Deg реализуем метод sound. Теперь, когда мы вызываем sound для
экземпляра Deg, он вернет строку "Woof!".
class Cat (Animal): — создаем класс Cat, который также наследует от
Animal. И он тоже обязан реализовать метод sound.
def sound(self):
return "Meow!"
В классе Cat определяем метод sound, который возвращает "Meow!".
# Использование
animals = (Dog(), Cat()]
Создаем список animals, который содержит классы Dog и Cat. Теперь у нас
есть два объекта, каждый из которых представляет конкретное животное.
for animal in animals:
print(animal.sound())
Перебираем каждый объект в списке animals и вызываем их метод sound.
Поскольку каждый класс реализовал этот метод, вывод будет:
Woof!
Meow!
Таким образом, мы увидим "Woof!" от собаки и "Meow!" от кошки.
Код демонстрирует использование абстрактных классов и методов
в Python, позволяя создать четкую структуру для разных типов животных,
которые должны реализовать определенное поведение (в данном случае —
издавать звук).
Абстракция реализуется не только через наследование, но и через ком-
позицию, где один класс использует другой в качестве составной части. Это
позволяет избегать жесткой зависимости между классами.
class Engine:
def start(self):
return "Engine started"
class Car:
def __init_ (self):
self.engine = Engined # Композиция
def start (self):
return self.engine.start() + " in the car"
my car = Car()
print(my_car.start()) # Вывод: Engine started in the car
pass
class Oog(Animal):
def sound(self):
return "Woofl"
class cat(Animal):
def sound(self):
return "Meow!"
w Использование
animals - [Oug(), Cat()J
for animal in animals:
print(animal.$ound())
woof!
Meow!
0 class Engine:
def start(self):
return "Engine started"
class Car:
def ___init__(self):
self-engine « EngineO » композиция
def start(self):
return self.engine.start() ♦ " in the car"
my_car - Car()
print(my_car.start()) w В* *4вод: Engine started in the car
Engine started in the car
- Ф 4- V 0 : —
s__________.____________J
Рис. 7.16
Здесь класс Car использует класс Engine в качестве своей составной части,
что демонстрирует принцип композиции — один из ключевых механизмов
абстракции в объектно ориентированном программировании. Композиция
позволяет строить сложные объекты из более простых, четко разграничи-
вая их ответственности. В данном случае автомобиль (Саг) «имеет» двигатель
(Engine) как свою часть, а не «является» двигателем, что отражает реальное
отношение между этими сущностями.
Такое проектирование дает несколько преимуществ:
• Гибкость: можно легко заменить реализацию Engine на другую (напри-
мер, электрический двигатель), не меняя код класса Саг.
• Повторное использование: класс Engine может использоваться и в дру-
гих контекстах (например, в классе Motorcycle).
• Инкапсуляция: внешний код взаимодействует с Саг, не зная деталей
реализации Engine.
Пример демонстрирует абстракцию через композицию.
class Engine: — создаем класс с именем Engine, который предел авляет со-
бой двигатель. Он будет содержать методы и свойства, связанные с работой
двигателя.
def start(self):
return "Engine started"
Внутри класса Engine определяем метод start, который возвращает стро-
ку "Engine started". Это симулирует запуск двигателя.
class Саг: — создаем класс Саг, который представляет собой автомобиль.
Этот класс будет использовать двигатель, который мы определили ранее.
def__init_ (self):—определяем специальный метод init_ .конструк-
тор класса. Он вызывается автоматически при создании нового объекта Саг.
self.engine = Engine() # Композиция — внутри метода init_ создаем
новый объект Engine и присваиваем его атрибуту self .engine класса Саг. Это
пример композиций, где класс Саг включает в себя объект класса Engine в ка-
честве компонента.
def start (self): — определяем метод start для класса Саг. Он вызывает-
ся для запуска автомобиля.
return self .engine.start () + " in the car" — внутри метода start вы-
зываем метод start у объекта engine, который создали ранее. Затем добавля-
ем строку " in the саг" к результату. Это означает, что, запуская машину, мы
также запускаем двигатель. В результате будет возвращена строка, которая
говорит, что двигатель запущен в автомобиле.
my car = Саг () — создаем экземпляр класса Саг и присваиваем его пере-
менной ту_саг. При этом автоматически будет вызван метод init , созда-
ющий объект Engine внутри шу_саг.
print (my_car.start ()) f Вывод: Engine started in the car — вызыва-
ем метод start у объекта my_car и печатаем результат. Этот метод запускает
двигатель через объект Engine, а затем добавляет уточнение о том, что это
происходит в автомобиле. В результате на экране появится строка "Engine
started in the car".
Код демонстрирует использование композиции, где класс Саг включает
двигатель как компонент, а также то, как можно организовать взаимодейс-
твие между классами, чтобы поддерживать ясность и структурированность
кода.
Абстракция усиливается через применяемые шаблоны проектирова-
ния, такие как адаптеры или декораторы, которые изменяют интерфейс
объекта или добавляют новую функциональность без изменения его
структуры.
class OldSystem:
def old_nethod(self):
return "Old method"
class Adapter:
def init (self, old_system):
self.old_system = old_syatem
def newjnethod(self):
return self .old_system.old_m.ethod () + " adapted tc new method"
old_system = OldSystem()
adapter = Adapter(old system)
print(adapter.new_method()) # Вывод: Old method aaaptea tc new method
sej.r .etqgine ttigitieu « яимпизмции
def start(self):
return self.engine.start() + " in the car*
му_car - Car()
print(ey_car.start()) • Вывод: Engine started in the car
Engine started in the car
-----------------------------------------------------------------------------------Ф Ф V 0 :
{5 class OldSysten: |
def old jnethod(self):
return "old Method*
class Adapter:
def __init_(self, old.systen):
self.oldsystee - oldsysten
def new_nethod(self):
return self.old_systen.oldjaetbod() ♦ " adapted to new Method*
oldsystem oldSysteeQ
adapter • Adapter(old_systew)
print(adapter.new_nethod()) ft Вывод Old Method adapted to new Method
Old Method adapted to new Method
class Engine:
def start(self):
return "Engine started"
class Car:
def _init_(self):
self.engine • Engine()
Рис. 7.17
Здесь адаптер представляет старую систему через новый интерфейс, пока-
зывая, как абстракция улучшает совместимость между разными системами.
class OldSystem: — создаем класс с названием OldSystem, который пред-
ставляет устаревшую систему или интерфейс.
def old_methcd(self):
return "Old method"
Внутри класса OldSystem. определяем метод old_method, вызов которой воз-
вращает строку "Old method". Этот метод предоставляет функциональность
устаревшей системы.
class Adapter: — создаем класс Adapter, который будет служить адаптером,
позволяющим интегрировать старую систему с новой интерфейсной частью.
def _init_(self, oldsystem):—определяем конструктор init ^ко-
торый вызывается при создании нового объекта Adapter. Он принимает один
аргумент old system, который будет экземпляром класса OldSystem.
self .old_system = old_system— внутри метода инициализации сохраняем
ссылку на переданный экземпляр old system в атрибуте self .old system. Это
позволяет адаптеру взаимодействовать со старой системой.
def new_method(self): — определяем метод newjmethcd, который предостав-
ляет новый интерфейс для работы с адаптированной функциональностью.
return self.31d_system.old_method() + " adapted to new method" — внутри
new_method вызываем метод oldjnethod у объекта self.old_system, получаем его
результат и добавляем к нему строку " adapted to new method". Это означа-
ет, что мы адаптируем выходные данные старого метода к новому интерфейсу.
old_system = OldSystem () —создаем экземпляр класса OldSystem и присва-
иваем его переменной old system. Это наша старая система.
adapter = Adapter (old_system) —создаем экземпляр класса Adapter, пе-
редавая ему объект old system. Таким образом, адаптер будет использовать
старую систему.
print(adapter.newjnethod()) f Вывод: Old method adapted to new method —
вызываем метод newjnethod у адаптера и печатаем результат. Этот метод об-
ращается к старой системе, получает результат от oldjnethod, добавляет до-
полнительный текст и возвращает "Old method adapted to new method". Это
выводится на экран.
Код демонстрирует пример использования паттерна адаптер, который
позволяет переносить функциональность устаревшей системы к новому ин-
терфейсу без изменения структуры самой старой системы.
Хотя наследование позволяет создавать иерархии классов, иногда лучше
использовать композицию. При этом объект включает в себя один или не-
сколько объектов других классов, что позволяет избежать проблем с «алмаз-
ным» наследованием.
class Engine:
def start(self):
return "Engine started"
class Car:
def _init_(self):
self.engine = Engine()
def start(seif):
return self.engine.start() + " - Car is ready to go!"
car = Car()
print(car.start()) fr Вывод: Engine started - Car is ready to go!
old_systee OidSystemQ
adapter = Adapter(old_system)
printfadapter.new_method()) # в^вод: old method adapted to new method
Old method adapted to new method
Q class engine:
def start(self)!
return "engine start nd"
class Car:
def _____init__(self):
self .engine - tngineO
def start(self):
return self.engine.start() + “ - Car is ready to gol"
car Car<)
print(car.startt)) » Вывод: engine started - Car is ready to gol
— Engine started - Car is ready Io gvl
Ч. ........ .............. ................... ...................
class CPU:
def freeze(self):
print(”CPU frozen")
def jumptself, position):
print(f"Jumping to jposition}")
def execute(self):
print("Cxeculing")
Рис. 7.18
В этом примере класс Саг использует объект Engine, демонстрируя, как
композиция предоставляет независимое поведение без иерархической слож-
ности.
Разберем каждую строчку кода.
class Engine: — создаем класс Engine, который представляет собой объект
двигателя. Он будет содержать методы и свойства, относящиеся к нему,
def start (self):
return "Engine started"
В классе Engine определяем метод start, который возвращает строку
"Engine started". Он симулирует запуска двигателя.
class Саг: — создаем класс Саг, который представляет автомобиль. Он
будет использоваться для создания объектов автомобилей,
def init (self):
self.engine = Engine()
Метод init (правильно __________init_ ) должен инициализировать объект Car.
Внутри него создаем новый экземпляр класса Engine и присваиваем его
свойству self .engine. Каждый объект Саг будет содержать объект Engine, что
является примером композиции — создание сложного объекта (машины)
с помощью других объектов (двигателя).
def start(self):
return self.engine.start() + " - Car is ready to go!"
Определяем метод start для класса Car, который вызывает метод start у объ-
екта self .engine и добавляет к его результату строку " - Car is ready to go!".
Это показывает, как класс Саг использует функциональность класса Engine.
car = Саг () — создаем новый объект саг класса Саг. В процессе создания
объекта вызовется метод _init (который здесь неправильно назван init)
и будет инициализирован объект Engine.
print(car.start()) S Вывод: Engine started - Car is ready to go! —вы-
зываем метод start на объекте car, который, в свою очередь, вызывает ме-
тод start на объекте engine и выводит результат. На экран выводится строка
"Engine started - Car is ready to go!", что демонстрирует работу как дви-
гателя, так и автомобиля.
Почему это иллюстрирует композицию вместо наследования:
1. Составные части. В данном примере Саг — составной объект, содер-
жащий объект Engine. Это означает, что Саг использует (содержит) Engine,
а не наследует от него. Это ключевой момент композиции — использование
объектов внутри других объектов.
2. Гибкость. Если бы мы использовали наследование, то могли бы создать
Саг как подкласс Engine, что неприменимо, так как не каждый автомобиль
является «двигателем». С помощью композиции мы можем легко менять, за-
менять или изменять двигатели, не трогая структуру класса Саг.
3. Избежание проблемы наследования. При сложной иерархии классов
с наследованием это могло бы привести к проблемам (например, «алмазное»
наследование). Композиция позволяет этого избежать, так как объекты взаи-
модействуют между собой, не создавая классических иерархий.
Этот код — яркий пример композиции, иллюстрирующий создание слож-
ных объектов с использованием более простых в качестве компонентов.
Фасад — это паттерн проектирования, который предоставляет упрощен-
ный интерфейс к сложной подсистеме или набору интерфейсов. Используя
абстракцию, фасад скрывает сложность и делает систему более удобной для
использования.
class CPU:
def freeze(self):
print("CPU frozen")
def jump(self, position):
print(f"Jumping to {position}")
def execute(self):
print("Executing")
class Memory:
def load(self, position):
print(f"Loading from {position}")
class Computer:
def ________init____(self):
self.cpu = CPU()
self.memory = Memory()
def start_computer(self):
self.cpu.freeze()
self.memory.load("0x00")
self.cpu.jump("UxOO")
self.cpu.execute()
computer = Computer()
computer.start computer()
© class CPU:
def freeze(self):
print("CPU frozen")
def jump(self, position):
print(f"Jumping to {position}")
def execute(self):
print("Executing")
class Memory:
def load(self, position):
print(f"Loading free {position}")
class Computer:
def__init_c(self):
self.cpu CPU()
self.memory Memory()
def start_computer($elf):
self.cpu.freeze()
self.memory.load("0x00")
self. cpu.jump("0x00")
self.cpu.execute()
computer - Computer^)
computer.start_computer()
••• CPU frozen
Loading from 0x00
Jumping to 0x00
Executing
class Car:
Рис. 7.19
Здесь класс Computer представляет собой фасад, который упрощает взаи-
модействие с более сложными классами CPU и Memory, скрывая детали ре-
ализации.
Разберем каждую строку кода.
class CPU: — создаем класс CPU, который представляет центральный про-
цессор компьютера. Он будет содержать методы, связанные с его работой.
def freeze(self):
print("CPU frozen")
Определяем метод freeze, который выводит на экран сообщение о замо-
розке процессора. Это может означать, что другие операции в процессоре
приостановлены.
def jump(self, position):
print(f"Jumping to [position}")
Метод jump принимает позицию в памяти и выводит сообщение о том, что
процессор переходит на указанную позицию.
def execute(self):
print("Executing")
Метод execute выводит надпись "Executing", что подразумевает выполне-
ние каких-то инструкций процессора.
class Memory: — создаем класс Memory, который представляет собой па-
мять компьютера и содержит методы для работы с ней.
def load(self, position):
print(f"Loading from (position}")
В методе load происходит загрузка данных из указанной позиции в памя-
ти. Он также выводит сообщение, указывающее позицию, из которой загру-
жаются данные.
class Computer: — создаем класс Computer, который выступает в качестве
фасада для более сложной подсистемы (объектов CPU и Memory).
def init(self):
self.cpu = CPU()
self.memory = Memory()
Определяем конструктор (правильно init ), который инициализирует
объект Computer. Он создает экземпляры классов CPU и Memory, привязывая их
к атрибутам объекта self.cpu и self .memory.
def start_computer(self): — метод start_computer объявляет последо-
вательность действий для запуска компьютера, которая требует взаимодейс-
твия как с ЦП, так и с памятью.
self .cpu. freeze () — в первой строке метода start_computer вызываем ме-
тод freeze для процессора, что инициирует процесс запуска.
self .memory. Ioad("0x00") — вызываем метод load у памяти, который за-
гружает данные из нулевой позиции (ОхОС).
self .cpu. jump("Gx')0") — вызываем метод jump для процессора, который
устанавливает текущую позицию для выполнения инструкций в памяти.
self .cpu.execute() — вызываем метод execute, что обозначает выполне-
ние инструкции процессором.
computer = Computer () —создаем новый объект computer класса Computer.
computer.start computer() — вызываем метод start computer на объекте
computer, который запускает последовательность действий для инициализа-
ции системы.
Почему этот пример иллюстрирует фасад:
1. Упрощение интерфейса. Класс Computer предоставляет простой ин-
терфейс для взаимодействия с несколькими сложными подкомпонентами
(ЦП и памятью). Вместо того чтобы напрямую взаимодействовать с CPU
и Memory, необходимо лишь вызвать метод start computer.
2. Сокрытие сложности. Паттерн фасад скрывает детали реализации
и сложности взаимодействия между компонентами, предоставляя более по-
нятный и удобный интерфейс. Достаточно знать, что нужно сделать, — за-
пустить компьютер, не вникая в детали работы ЦП и памяти.
3. Облегчение взаимодействия. Фасад позволяет управлять процессом, не
заботясь о том, как именно реализованы взаимодействия в подсистемах. Код
становится более структурированным и поддерживаемым.
Код иллюстрирует использование паттерна фасад, упрощая интерфейс
и скрывая сложности взаимодействия между объектами.
Классы и объекты: строительные блоки ООП
Класс — это абстрактная спецификация, определяющая структуру и пове-
дение объектов, которые его наследуют. В Python все является объектом,
включая примитивные типы данных, такие как числа и строки, а также более
сложные структуры, например классы. Это шаблон для создания объектов,
который определяет набор атрибутов (состояний) и методов (поведения).
Объект — это экземпляр класса, его реализация с определенными значе-
ниями атрибутов.
Псевдокод ниже описывает процесс создания класса, инициализации его
атрибутов с помощью конструктора, определения методов и создания объек-
тов класса с использованием определенных методов.
Синтаксис:
Класс ИмяКлаоса:
Метод __init_(self, параметры):
# Инициализация атрибутов объекта
self.атрибут! = значение!
self.атрибут2 = значение2
# и так далее для других атрибутов
Метод имяМетода(self, параметры):
4 Реализация метода
сделать что-то с атрибутами
# Создание объекта (экземпляра) класса
объект! = ИмяКласса(аргументы)
# Вызов методов объекта
объект!.имяМетода(аргументы)
Представьте, что у вас есть класс "Автомобиль". Он может содержать раз-
личные свойства — цвет, марку, модель и скорость, — а также методы, поз-
воляющие автомобилю выполнять действия, например двигаться, тормозить
или заправляться.
Пример:
1. Класс "Автомобиль".
class Саг:
def __init_(self, brand, model, color):
self.brand = brand
self.model = model
self.color = color
self.speed = 3
def accelerate(self, increase):
self.speed += increase
print(f"The (self.color} {self.brand) {self.model) is now
going {self.speed} km/h.")
def brake(self):
self.speed = 0
prir.t(f"The (self.color} {self.brand) {self.model} has
stopped.")
Разберем каждую строчку кода.
class Car: — определяет новый класс с именем Саг. Это шаблон (или мо-
дель) для создания объектов (конкретных автомобилей), включающий в себя
свойства и методы, которые будут использоваться этими объектами.
def __init__(self, brand, model, color): —специальный метод под на-
званием конструктор. Вызывается при создании нового объекта класса Саг.
Он принимает параметры brand, model и color, которые используются для
инициализации характеристик автомобиля.
self .brand = brand — присваивает переданное значение параметра brand
атрибуту brand текущего объекта (обозначается self), self указывает на со-
здаваемый экземпляр класса и позволяет сохранить состояние объекта.
self .model = model — аналогично предыдущей строке, эта строка сохраня-
ет значение параметра model как свойство model объекта.
self.color = color — присваивает значение параметра color атрибуту
color текущего объекта.
self, speed = С — создает атрибут speed и инициализирует его значением
0. Оно будет использоваться для отслеживания скорости автомобиля.
def accelerate (self, increase): — это метод класса, который называется
accelerate. Он принимает параметр increase, который указывает, на сколько
нужно увеличить скорость автомобиля
self .speed += increase — увеличивает текущую скорость автомобиля на
значение, переданное в параметре increase.
print(f"The {self.color) }self.Brand} {self.model} is now going {self,
speed} km/h.") — выводит на экран сообщение, которое информирует о теку-
щей скорости автомобиля и его характеристиках (цвет, марка и модель).
def brake (self): — это метод класса, который называется brake. Он не
принимает параметров и используется для остановки автомобиля.
self .speed = 0 — устанавливает скорость автомобиля 0, то есть автомо-
биль стоит на месте.
print(f"The {self.color} {self.brand} {self.model} has stopped.") —
выводит на экран сообщение о том, что автомобиль остановился, указывая
его характеристики (цвет, марка и модель).
Код определяет класс Саг, который может быть использован для создания
объектов автомобилей с определенными характеристиками и возможностью
изменения скорости. Он имеет методы для увеличения скорости (accelerate)
и остановки автомобиля (brake).
2. Создание объектов.
Теперь, используя класс "Автомобиль", мы можем создать несколько
объектов:
carl = Car("Toyota", "Camry", "red")
car2 = Car("Honda", "Civic", "blue")
Разберем, что делает каждая строчка в примере создания объектов carl
и саг2 класса Саг.
carl = Car ("Toyota", "Camry", "red"): - создает новый объект (экземпляр)
класса Саг и присваивает его переменной carl. Вызов конструктора Саг проис-
ходит с передачей трех аргументов: "Toyota" (марка), "Camry" (модель) и "red"
(цвет). Во время выполнения конструктора происходит инициализация атри-
бутов orand, model, color и speed (установленный на 0) для объекта carl.
car2 = Car ("Honda", "Civic", "blue"): - также создает новый объект
класса Саг и присваивает его переменной саг2. В данном случае конструкто-
ру передаются другие аргументы: "Honda" (марка), "Civic" (модель) и "blue"
(цвет).
В результате выполнения конструктора Саг, объект саг2 будет иметь свои
собственные атрибуты brand, model, color и speed, инициализированные со-
гласно переданным аргументам.
Таким образом, в этих строках создаются два отдельных объекта класса
Саг с уникальными характеристиками: carl представляет красную Toyota
Camry, а саг2 — синюю Honda Civic. Каждый из этих объектов имеет собс-
твенные значения атрибутов и может использовать методы класса Саг, такие
как accelerate () иЬгаке().
3. Взаимодействие с объектами.
Теперь мы можем использовать методы, определенные в классе, чтобы уп-
равлять этими объектами:
ca rl.accelerate(63) # Вывод: "The red Toyota Camry is now going
60 km/h."
car2.accelerate(50) # Вывод: "The blue Honda Civic is now going
50 km/h."
carl.brakeO # Вывод: "The red Toyota Camry has stepped."
Здесь класс "Автомобиль" служит шаблоном для создания конкретных ав-
томобилей, таких как carl (красная Toyota Camry) и саг2 (синяя Honda Civic).
Каждый объект имеет собственные параметры (цвет, марка и модель) и вы-
полнять действия с помощью методов (ускорение и торможение).
Разберем, что делает каждая из этих строк кода, вызывающих методы
у объектов carl и саг2.
carl .accelerate (63): - вызывает метод accelerate у объекта carl, кото-
рый представляет красную Toyota Camry. В качестве аргумента методу пере-
дается значение 60, что означает, что скорость автомобиля будет увеличена на
60 км/ч. Внутри метода accelerate к текущей скорости (которая в начале была
0) добавляется 60, и установка self. speed теперь будет равна 6С. Затем выпол-
няется print, и вывод будет: "The red Toyota Camry is now going 60 km/h."
car2.accelerate(53): — вызывает метод accelerate у объекта car2, кото-
рый представляет синюю Honda Civic. Методу передается значение 50, чтобы
увеличить скорость на 50 км/ч. Текущая скорость для саг2 также изначально
О, а после вызова метода станет 50. Затем выводится сообщение: "The blue
Honda Civic is now going 50 km/h."
carl.brakeO: — вызывает метод brake у объекта carl (красная Toyota
Camry). Метод brake не принимает аргументов и устанавливает self. speed на
О — автомобиль стоит на месте. После этого выполняется строка print и вы-
водится сообщение: "The red Toyota Camry has stopped."
Эти строки кода выполняют действия с объектами carl и саг2, увеличивая
их скорость и останавливая один из автомобилей. Метод accelerate меняет
скорость объекта и уведомляет о новой, в то время как метод brake останав-
ливает автомобиль и тоже уведомляет об этом.
Пример класса:
class Cat:
def___init___(self, name, age):
self.name = name # атрибут объекта
self.age = age
def mecw(self): # метод
print(f"(self.name} говорит: Мяу!")
# Создание объекта
my cat = Cat ("Барсик", 3)
my_cat.meow() # Вывод: Барсик говорит: Мяу!
seiT.cuxur • сими1
self,speed • 0
def accelcratefself, increase):
self.speed ♦- increase
print(f"The {self.color} (self.brand) {self.Model) is now going {self.speed} км/h.")
def brakc(self):
self.speed 0
print(f"The [self.color) {self.brand} {self.node!} has stopped.”)
---------------------------------------------------------------------------------------------------------------------Ф У 0 • -
Q class Cat:
def ____init__(self, naee, age):
self.гаме -ane » атрибут объекта
self.age age
def neow(self): « метод
print(f"{self.ламе} говорит: Мяу!")
» Создание объекта
y_cat Cat(“Барсик”, 3)
y_cat.eeow() в вывод: Барсик говорит: мяу! |
Барсик говорит: мяу!
class Math;
0staticnethod
def add(к, у):
return x ♦ у
gclassnetbod
Рис. 7.20
В этом примере класс Cat определяет структуру и поведение объектов,
а метод init нужен для инициализации нового экземпляра класса.
Ключевые понятия:
_init_— специальный метод, выполняемый при создании объекта. Он
инициализирует атрибуты объекта и может принимать произвольное коли-
чество аргументов.
self — ссылка на текущий экземпляр класса для доступа к атрибутам
и методам объекта.
Динамическое добавление атрибутов: в Python возможно добавлять но-
вые атрибуты к объектам во время выполнения программы, однако это не
рекомендуется с точки зрения инкапсуляции.
Атрибуты и методы класса
Атрибуты могут быть определены как инстансные (принадлежат конкрет-
ному объекту) и статические (принадлежат классу и общие для всех объектов).
Методы могуч быть обычными, класс-методами и статическими методами.
Статические методы и класс-методы:
class Math:
(?staticmethod
def add(x, у):
return x + у
(jclassmethod
aef multiply(cis, x, y):
return x * у
print(Math.add(3, 5)} # Вывод: 8
print(Math.multiply(3, 5)) f Вывсд: 15
------------------------------------------------------------------------------------------------------------------- ф Ф X 0 : —
Q class Hath: |
^staticeethod
def add(x, y);
return x ♦ у
^classeethod
def Multiply^!*, x, y):
return x • у
print(Math.add(3, 5)) « Вывод: 8
print(Math.multiply(3, 5)) а Вывод: 15
... 8
15
class BankAccount:
def ____init_(self, balance):
self.__balance balance приват»вл атрибут
def get balance(self): « геттер
return self.___balance
account BankAccount(ibBe)
print(account.get_balance()) • 1BO0
a account.___balance а Ошибка: атрибут не найден
class BankAccount:
def _init__(self, balance):
Рис. 7.21
1.class Math:
Что делает? Определяет новый класс с именем Math.
Зачем? Классы служат шаблоном для создания объектов и могут объеди-
нять данные и функции для выполнения определенных задач.
2.0staticmethod
Что делает? Декоратор, который определяет, что следующий метод явля-
ется статическим.
Зачем? Статические методы не зависят от экземпляров класса или его со-
стояния, и их можно вызывать на уровне класса.
3. def add(x, у):
Что делает? Определяет статический метод add, который принимает два
параметра.
Зачем? Этот метод выполняет конкретную задачу — суммирует два числа.
4. return х + у
Что делает? Возвращает сумму параметров х и у.
Зачем? Позволяет получить результат, который может быть использован
в других частях программы.
5. @classmethod
Что делает? Декоратор, который обозначает, что следующий метод явля-
ется класс-методом.
Зачем? Класс-методы работают с самим классом и могут изменять его со-
стояние, если это необходимо.
6. def multiply(cls, х, у):
Что делает? Определяет класс-метод multiply, принимающий класс (cis),
а также два параметра.
Зачем? Выполняет задачу умножения двух чисел и может быть вызван че-
рез сам класс или его экземпляры.
7. return х * у
Что делает? Возвращает произведение параметров х и у.
Зачем? Позволяет пользователю получить результат операции умноже-
ния.
8. print(Math.add(3, 5))
Что делает? Вызывает статический метод add у класса Math с аргументами
3 и 5.
Зачем? Позволяет выполнить операцию сложения и вывести результат на
экран (в данном случае 8).
9. print(Math.multiply(3, 5))
Что делает? Вызывает класс-метод multiply у класса Math с аргумента-
ми 3 и 5.
Зачем? Позволяет выполнить операцию умножения и вывести результат
на экран (в данном случае 15).
Таким образом, этот код создает класс Math, который содержит статичес-
кий метод для сложения и класс-метод для умножения. Оба метода вызыва-
ются на уровне класса и выводят результаты выполнения арифметических
операций.
Инкапсуляция, наследование и полиморфизм
(дополнительные примеры)
Инкапсуляция, наследование и полиморфизм — основополагающие кон-
цепции ООП, обеспечивающие модульность, повторное использование кода
и гибкость программного обеспечения.
Инкапсуляция
Инкапсуляция — это механизм сокрытия внутренней реализации класса
и защиты его данных. В Python используются соглашения для реализации
инкапсуляции, а не строгие языковые конструкции.
_protected_attribute — защищенный атрибут, доступ к которому возмо-
жен из методов самого класса и его подклассов.
private_attribute — псевдоприватный атрибут, имя которого искажается
при доступе через_getattribute_для предотвращения случайного доступа.
Пример:
class BankAccount:
def _init_(self, balance):
self._balance = balance # приватный атрибут
def get_balar.ce (self): # геттер
return self, balance
account = BankAccount(1000)
print(account.get_balance()) # 1000
# account, balance f Сшибка: атрибут не найден
gclassnethod
det multiply(cls, x, y):
return x • у
print(’Hatr..dddi3, 5)) я 8
print(Math.nultiply(3, 5)) Я Вывод: 15
8
15
Q class BankAccount:
def ____init_(self, balance):
self.__balance • balance Я приватный атрибу:
def get_balance(self): я геттер
return self.__balance
account = BankAc:ount(10O0)
print(accounl.get_balance()) # 1000
ч account._balance я Ошиока: атрибут не найден
... 1000
Q class BankAccount:
def ______init_(self, balance):
self._balance = balance я приватный атрибут
def deposit(self, anount):
Рис. 7.22
Инкапсуляция в Python достигается через модификаторы доступа, ко-
торые позволяю! скрывать данные от внешнего мира, обеспечивая защиту
внутреннего состояния объекта.
С помощью одного или двух подчеркиваний можно сделать атрибуты за-
щищенными или приватными.
Пример:
class BankAccount:
def________init__(self, balance):
self.___balance = balance # приватный атрибут
def deposit(self, amount):
self._______balance += amount
def get oalance(self):
return self.________balance
account = BankAccount (Ю0)
account.deposit(53)
print(account.get_balance()) # Вывод: 150
class daпкAc count:
def ___init__(self, balance):
self.__balance = balance # приватный атрибут
def get_balance(self): « геттер
return self.___balance
account = ВапкАсcount(1000)
print(account.get_balance()) » 1000
я account.___balance » Оиибка: атрибут не найден
1000
Q class BankAccount:
def ___init__(self, balance):
self.___balance « balance # приватный атриоут
def deposit(self, amour.tl:
self.___balance + amount
def getbalance(self):
return self.___balance
account = BankAccount(lee)
account.deposit(50)
print(account.get balanced) г вывод: 150
... 150
Рис. 7.23
В Python инкапсуляция реализуется с помощью модификаторов доступа,
которые позволяют скрыть данные от внешних объектов, обеспечивая защи-
ту внутреннего состояния класса. Приватные атрибуты можно создать с по-
мощью одного или двух подчеркиваний, чтобы они были защищенными или
полностью приватными.
Пример:
class BankAccount:
def_______init__(self, balance):
self.___balance = balance ff Приватный атрибут
def deposit(self, amount):
self., balance += amount # Увеличиваем баланс на указанную сумму
def get_balance (self):
return self.__balance # Возвращаем текущий баланс
account = BankAccount(100) ff Создаем экземпляр класса BankAccount с на-
чальным балансом 100
account.deposit(50) # Вносим 50 на счет
print(account.gec_oalance()) # Печатаем текущий баланс: 150
def deposit(self, amount):
self._balance += amount
def get_balance(self):
return seif._balance
account = BankAccountfieo)
a< count.dcposit(S0)
printfaccount.get_balance()) # Вывод: ISO
— 150
______________________________________________ + Код __ + Тексг ,
0 class BankAccount:
def _____init_(self, balance):
self._balance balance # приватный атрибут
def deposit(self, amount):
self._balance + amount # Увеличиваем баланс на указанную сумму
def grt.balance(self):
return self ._balance •: Возвращаем текущий баланс
account • BankAccount) 100) # создаем ,>кэемлл><р класса BankAccount с начальном балансом 100
account.deposit(50) « В-осим 5и на счет
print(account.geT_balance()) # печатаем текущий баланс: 150
150
-
Рис. 7.24
Разберем значение каждой строчки:
1. class BankAccount: — определяет новый класс с именем BankAccount,
представляющий банковский счет.
2. def _init__(self, balance) : — определяет метод инициализации, ко-
торый вызывается при создании нового объекта класса. Принимает началь-
ный баланс.
3. self._balance = balance: —создает приватный атрибут_____________balance, ко-
торый хранит значение баланса. Приватность позволяет защитить его от до-
ступа извне.
4. def deposit (self, amount): — определяет метод deposit, который поз-
воляет вносить деньги на счет, принимая сумму пополнения.
5. self.___balance += amount: —увеличивает значение приватного атрибу-
та ____________balance на сумму, переданную методу.
6. def qet_balance (self): — определяет метод get_balance, который воз-
вращает текущее значение баланса.
7. return self, balance: — возвращает значение приватного атрибута
Balance из метода.
8. account = BankAccount (100): — создает новый объект класса BankAccount
и устанавливаем начальный баланс ЮС.
9. account.deposit (50): — вызывает метод deposit для увеличения балан-
са на 50.
10. print (account, get balanced ): — печатает новый баланс, полученный
с помощью метода getjbalance, который должен быть равен 150.
Наследование
Наследование позволяет создавать новые классы на основе существующих,
наследуя их структуру и поведение. Это способствует повторному использо-
ванию кода и модульности.
Пример:
class Animal:
def speak(self):
raise NotlmplementedError("Метод должен быть переопределен")
class Dog(Animal):
def speak(self):
return ’Тав!"
class Cat(Animal):
def speak(self):
return "Мяу!"
animals = [Dog(), Cat()]
for a in animals:
print(a.speak()) # Полиморфизм в действии
Наследование реализовано в строках:
python
class Dog(Animal):
class Cat( Animal):
Здесь классы Dog и Cat наследуются от базового класса Animal. Это зна-
чит, что:
• Dog и Cat автоматически получают все атрибуты и методы класса
Animal;
• они могут переопределять (заменять) методы родительского класса;
• сохраняется иерархия «родитель-потомок»: Animal -> Dog, Animal -> Cat.
def deposit(self, amount):
self.___balance +» amount tt Увеличиваем баланс на указанную сумму
def get balance(self):
return self.___balance # возвращаем текущий баланс
account BankAcrount(100) к Создаем экземпляр класса BankAccount с начальным балансом 100
account.deposit(50) tt Вносим 50 на счет
print(account.get_balance()) # Печатаем текущий баланс: 150
150
Q class Animal: |
def speak(self):
raise Notlmplementedfrror("Метод должен быть переопределяй")
class Dog(Animal):
def speak(self):
return "Гав!"
class Cat(Animal):
def speak(self):
return "мяу!"
animals = (DOgi), Cat()]
for a in animals:
print(a.speakc)) # Полиморфизм 8 действии
— гас!
мяу I
ч __________________________________
Рис. 7.25
Подробное описание кода
1. Базовый класс Animal
python
class Animal:
def speak(self):
raise NotlmplementedError(«MeTOfl должен быть переопределен»)
Назначение: абстрактный базовый класс, задающий общий интерфейс
для всех животных.
Метод speak ().
• объявлен, по не реализует конкретное поведение;
• при вызове поднимает исключение NotlmplementedError с сообщением;
• служит «шаблоном»: наследники обязаны переопределить этот метод.
Это пример абстракции — мы определяем, что у любого животного дол-
жен быть звук (speak), но не указываем, какой именно.
2. Класс Dog (наследник Animal)
python
class Dog( Animal):
def speak(self):
return “Гав!”
Наследование: Dog получает все от Animal, но переопределяет speak ().
Переопределение метода: вместо поднятия исключения возвращает стро-
ку «1ав!».
Принцип подстановки Дисков: объект Dog можно использовать везде,
где ожидается Animal.
3. Класс Cat (наследник Animal)
python
class Cat( Animal):
def speak(self):
return “Мяу!”
Аналогично Dog, но возвращает «Мяу!».
Демонстрирует, как разные наследники предоставляют свою реализацию
одного метода.
4. Использование полиморфизма
python
animals = [Dog(), Cat()]
for a in animals:
print(a.speak(J) # Полиморфизм в действии
Список animals содержит объекты разных классов (Dog и Cat), но все
они — потомки Animal.
Цикл for:
• берет каждый объект а из списка;
• вызывает a.speak(), не зная точного типа объекта;
• благодаря переопределению метода каждый объект возвращает свой
звук.
Это полиморфизм, один и тот же вызов (speak ()) ведет к разному поведе-
нию в зависимости от типа объекта.
Ключевые концепции ООП в коде
Наследование
Dog и Cat наследуют от Animal, избегая дублирования кода.
Абстракция
Animal. speak () задает контракт, но не реализует его.
Полиморфизм
a.speak() работает для любого объекта в списке, несмотря на разные
классы.
Инкапсуляция
Каждый класс скрывает свою реализацию метода speak().
Итог
Код демонстрирует классическую иерархию наследования:
• Animal — общий интерфейс;
• Dog и Cat — конкретные реализации;
• полиморфизм позволяет обрабатывать объекты единообразно, несмот-
ря на различия в поведении
Полиморфизм
Полиморфизм — это способность объектов с одинаковым интерфейсом (ме-
тодом) вести себя по-разному в зависимости от их типа. Это достигается бла-
годаря наследованию и переопределению методов.
Ключевая ценность полиморфизма заключается в обеспечении гибкости,
расширяемости и снижения связности кода.
Теоретические основы
Полиморфизм реализуется через механизмы:
• наследования (создание иерархии классов);
• переопределения методов (изменение реализации в подклассах);
• динамического связывания (выбор реализации метода во время вы-
полнения).
Формально, если существует интерфейс с методом, и классы реализуют,
то вызов для объекта типа приведет к выполнению реализации.
Практические примеры реализации
Пример I. Иерархия фигур с абстрактным базовым классом
Суть примера
Демонстрирует классический полиморфизм через наследование и перео-
пределение методов. Абстрактный класс Shape задает контракт, а подклассы
(Circle, Rectangle) предоставляют специфическую реализацию.
Код:
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractinethod
def area(self) -> float;
pass
class CircIe(Shape):
def__init_(self, radius: float):
self.radius = radius
def area(self) -> float:
return 3.14159 * self.radius ** 2
class Rectangle(Shape):
def____init___(self, width: float, height: float):
self, width = width
self.height = height
def area(self) -> float:
return self.width * self.height
shapes = [Circle(5), Rectangle(4, 6)]
for shape in shapes:
print(f’’Площадь: {shape.area():.2f}”)
Разбор кода:
from abc import ABC, abstractmethod — подключаем инструменты для абс-
трактных классов.
class Shape(ABC) — абстрактный базовый класс, нельзя создать экземп-
ляр.
Qabstractmethod def area() —обязательный для реализации метод.
Circle(Shape) и Rectangle(Shape) — подклассы, реализующие area ().
shapes = [...] — список объектов разных типов с общим интерфейсом.
Пикл for — полиморфный вызов area () без проверки типа.
Результат:
Площадь: 78.54
Площадь: 24.00
Мяу!
ф from abc import ABC, abstractmethod
class Shape(ABC):
gabstractmethod
def area(self) -> float:
pass
class Circle(shape):
def ____init_(self, radius: float):
self.radius - radius
def area(self) -> float:
return 3.141S9 * self.radius •• 2
class Rectangle(Shape):
def _init_(self, width; float, height: float):
self.width » width
self.height • height
def area(self) •> float:
return self.width • self.height
shapes = (Circle(S), Rectangle(4, 6)]
for shape in shapes:
print(f"Площадь: ,shape.area():.2f}")
— Площадь: 78.54
площадь: 24.ee
Рис. 7.26(1)
Ключевые выводы:
Единый интерфейс (area ()) скрывает разную реализацию.
Код устойчив к добавлению новых фигур (например, Triangle).
Принцип подстановки Дисков соблюдается: подклассы заменяют базовый
класс.
Пример 2. Перегрузка метода через анализ типов
Суть примера
Показывает параметрический полиморфизм: один метод process () обра-
батывает разные типы данных, адаптируя поведение к входному аргументу.
Код:
class PolymorphicProcessor:
def process(self, data):
if isinstance(data, int):
return data * 2
elif isinstance(data, str):
return data.upper()
elif isinstancefdata, list):
return [self.process(item) for item in data]
else:
raise ТуреЕггог(Г’Неподдерживаемый тип: {type(data)}”)
processor = PolymorphicProcessor()
print! processor.process(42)) # 84
print(processor.process(“hello”)) # “HELLO”
print(processor.process([l, "a”, 3])) # [2, X 6]
Разбор кода:
def process(self, data) — метод с динамической типизацией.
isinstance(data, int) — проверка типа для целочисленных значений,
data.upper () — преобразование строки в верхний регистр.
Рекурсивная обработка списков: self .process (item).
TypeError — защита от неподдерживаемых типов.
Результат:
84
HELLO
[2, X 6]
Плоцадь: 78.Sd
Плоцадь: 24.00
© class PolymorphicProcessor: |
def proces$(self, data):
if isinstance(data, int):
return data 2
elif isinstance(data, str):
return data.upper()
elif isinstance(data, list):
return [self.processЦten) for item in data)
else:
raise ТуреЕггог(Е”неподдерживае*ьй тип: (type(data)}**)
processor PolymorphicProcessor()
printfprocessor.processtdi)) • 84
print(processor.process<_hello“)) • "HELLO”
print(processor.process((l, "a”, 3])) » [2, ’A', 6)
— 84
HELLO
(2, A’, 6]
free typing import Protocol
class Renderable(Protocol):
def render(self) -> str: ...
Рис. 7.26(2)
Ключевые выводы:
Полиморфизм достигается через анализ типа во время выполнения.
Метод универсален для разных структур данных.
Рекурсия позволяет обрабатывать вложенные структуры.
Пример 3. Полиморфизм через протоколы (интерфейсы)
Суть примера
Иллюстрирует утиную типизацию через протоколы: классы не наследуют
общий родитель, но соответствуют контракту Renderable, что обеспечивает
полиморфное поведение.
Код:
from typing import Protocol
class Renderable(Prolocol):
def render(self) -> str:...
class TextElement:
def__init_(self, content: str):
self.content = content
def render(self) -> str:
return f”<p> {self.content} </p>”
class ImageElement:
def___init__(self, src: str, alt: str):
self.src, self.alt = src, alt
def render(self) -> str:
return f’<img src=”{self.src}” alt=”{self.alt}”>’
class I.istElcment:
def___init__(self, items: list[str]):
self.items = items
def render(self) -> str:
items_html = “”.join(f”<li>{item}</li>” for item in self.items)
return f”<ul>(items_html}</ul>”
def render_all(elements: list [Renderable]) -> str:
return “”.join(element.render() for element in elements)
content = [
TextElement(“IlpjiBeT, мир!”),
ImageElement (“photo.jpg”, “Фото”),
ListElement( [“Пункт 1”, "Пункт 2”])
]
print(render_all(content))
Результат:
<р>Привет, MMp!</pximg src=”photo.jpg” ак=”Фото”хи1хИ>Пункт 1</
ИхИ>Пункт 2</lix/ul>
Разбор кода:
class Renderable(Protocol) — контракт с методом render ().
TextElement, ImageElement, ListElement — классы, реализующие прото-
кол.
render_all(elements: list[Renderable]) — функция, принимающая любые
объекты, соответствующие протоколу.
«».join(element.render()...) — полиморфный вызов render() для разнотип-
ных объектов.
Q from typing import Protocol
class Renderable(Protocol):
def render(seif) -> str: ...
class Textfleaent:
def________init__(self, content: str):
self.content • content
def render(self) -> str:
return f*<p>(s*lf,content}</p>"
class Imageslament:
def _______init__(self, sre: str, alt: str):
self.sre, self.alt sre, alt
def render(self) -> str;
return f'<img src«"{sclf.sre)" *lt»"{self.alt)">'
class ListElement:
def _______init__(self, items: list(str)):
self.items • items
def render(self) -> str:
iteas_html join(f"<li>(item}</li>" for item in self.items)
return f"<ul>{itemshtml}</ul>"
def render_ell (elements: list[Renderable]) •> str:
return join(element.rendert) for element in elements)
content ж (
TextElament("Привет, имр!"),
ImageE1ement("photo,jpg", "Фото"),
Li stElement(["Пункт 1", "Пункт 2"])
)
print(render_all(content))
ср>Лриает, MMpfC/pxiag sre«"photo.jpg" •Н»“Фото"Хи1хК>Пумхт 1</Нх11>Пумкт 2</liX/ul>
Рис. 7.26(3)
Ключевые выводы:
Нет наследования — только соответствие контракту.
Высокая гибкость: можно добавлять новые классы без изменения интер-
фейса.
Явная типизация через Protocol улучшает читаемость.
Общие выводы
Классический полиморфизм (Пример 1):
Основа: наследование и переопределение.
Плюсы: четкая иерархия, простота понимания.
Минусы: жесткая связь между классами.
Параметрический полиморфизм (Пример 2):
Основа: анализ типов во время выполнения.
Плюсы: универсальность, обработка сложных структур.
Минусы: потенциальное снижение производительности.
Утиная типизация (Пример 3):
Основа: соответствие контракту (протоколу).
Плюсы: слабая связанность, расширяемость.
Минусы: требует дисциплины в соблюдении контрактов.
Рекомендации по применению:
Используйте наследование для логически связанных сущностей.
Применяйте протоколы для слабосвязанных компонентов.
Избегайте чрезмерного анализа типов — это усложняет отладку.
Соблюдайте принцип едино геенной ответственности: каждый класс дол-
жен иметь одну причину для изменения.
Обработка исключений и итераторы
Обработка исключений позволяет управлять ошибками и непредвиденными
ситуациями в программе, обеспечивая ее стабильность и надежность. Итера-
торы предоставляют удобный способ обхода коллекций.
Собственные исключения:
class NegativeBalanceError(Exception):
pass
def withdraw(amount):
if amount < C:
raise NegativeBalanceError("Сумма не может быть отрицательной")
В этом примере определяется собственное исключение NegativeBalanceEr-
ror, которое может быть поднято при попытке снять отрицательную сумму
с банковского счета.
Итераторы
Итераторы — это объекты, позволяющие последовательно обходить элемен-
ты коллекции. В Python они реализуются через методы__iter и _next_ .
Пример:
class Countdown:
def _init_ (self, start):
self.current = start
def _ iter (self):
return self
def __next_(self):
if self.current <= 0:
raise Stoplteraticn
num = self.current
self.current -= 1
return num
for num
in Countdown (5):
print ( Ц co<it*nt))
<р>Привет, MMpl</p><ieg src«"pboto.jpg" а1Л=’Фото"Хи1ХН>Пункт К/НхИХТункт 2</liX/ul>
class NiegativeBalanceError(Exception):
pass
drf withdraw(amount):
if amount < 0;
raise Hegat1уеВа1апсеЕггог("Сумма не может 6*лъ отрицательной")
ф class Countdown:
def ________init___(self, start);
self.current ~ start
def iter (self):
return self
def next (self):
if self.current О 0:
raise Stopiteration
num a self.current
self.current -• 1
return num
for num in Countdcwn(5):
print(nun) # 5, 4, 3, 2, 1
5
4
3
2
1
import types
Рис. 7.27
Декораторы и метаклассы
Декораторы и метаклассы [88J — это продвинутые механизмы ООП, позво-
ляющие модифицировать поведение классов и их методов.
Декораторы классов
Декораторы классов используются для модификации поведения классов, та-
ких как добавление легирования или валидации.
Пример:
aef log methods(cis):
for name, method in cis._diet_.items():
if callable(method) and not name.startswith(" "):
setattr(cls, name, lambda self, *args,
_method=method, name=name, **kwargs:(
print(f"Вызван {_name}"),
_method(self,*args,**kwargs))[1])
return cis
@log_methods
class MyClass:
def test(self):
pass
ob] = MyClass()
obj.testf) # Вывод: "Вызван test"
0 import types
def log_Bethods(cls):
for name, attr in cl«.___diet___.it*Bt():
# Проверяем, является ли атрибут функцией и нс начинается ли с *___'
# чтобы избежать оборачивания специальных методов и атрибутов.
if isinstance(attr, typcs.FunctionType) and not na«e.startswith('_____’):
orig,inal_method « attr
def wrapper(self, “args, ““kwargs):
print(f’Вызван {ламе}*) • Легируем вызов метода
return origin»l_i»ethod(self, *args, ““kwargs) it Ьжлим оригинальный метод
» Заменяем оригинальный метод на обертку
»etattr(cls, ламе, wrapper)
return cl*
Plog method*
class MyClass:
def test(self):
pass.
obj « MyClassO
obj.test() • Вывод: "Вызван test"
Вызван ____doc__
class Mota(type):
def ___new_(cls, naae, bases, det):
det["version"] »1.0
return superO*__new(cls» nane, bases, det)
Рис. 7.28
Метаклассы
Метаклассы — это классы, создающие другие классы. В Python базовый мета-
класс — type.
Пример:
class Meta(type):
def new (cis, name, bases, det):
det["version"] =1.0
return super().__new___(els, name, bases, det)
class MyClass(metaclass=Meta):
pass
print(MyClass.version) # 1.0
Паттерны проектирования
Паттерны проектирования — это проверенные временем решения для часто
встречающихся проблем в программировании. Они обеспечивают структу-
рированность и повторное использование кода.
Singleton (Одиночка)
Паттерн Singleton гарантирует наличие в системе только одного экземпляра
класса.
class Singleton:
instance = None
def _new_(cls, *args, **kwargs):
if not cls._instance:
cis._ir.stance = super(). new (cis, *args,**kwargs)
return cis.-instance
ф Ф ♦ oo p (У В :
'’J1 0 if________MM_
ze*. 9 Создаем первый экземпляр
objl - Singleton("First instance")
print(f"objl data: {objl.data}") » выведет: First Instance
print(f"ld(objl)i (id(objl)}")
S Создаем второй экземпляр с другим значением
obj2 - Singleton("Second instance")
print (fob j2 data: [objl.data}“) а Все еце выведет: First Instance
print(f’id(obj2): (id(obj2)}") в Тот xe id. что и у objl
* Проверяем, что это од<и и тот хе объект
print(f"objl is obj2: {objl i* obj2}’) a True
w Обновляем данные мере* объект
objl.update_data("updated data")
print (fob j2 data after update: {obj2.data}") • Выведет: Updated data
• попытка создать третий экземпляр
obj3 • 5ingleton(“Third instance")
print(f"obj3 data: [objl.data}") • Все ewe выведет: Updated data
print(f"objl is obj3: {objl is obj3}’) • True
objl data: None
id(objl): 135834374759872
obj2 data: None
id(obj2). 135834374759872
objl is obj2: True
obj2 data after update: Updated data
objB data: Updated data
objl is obj3: True
Рис. 7.29
Фабричный метод
Фабричный метод используется для создания объектов без указания их кон-
кретного типа, что способствует гибкости и тестируемости.
class Button:
def render(self):
pass
class WindowsButtcn(Button):
def render(self):
return "Кнопка Windows"
class ButtonFactory:
def create_button(self, os_type):
if os type == "Windows":
return WinaowsButtor. ()
else:
raise ValueError("Неподдерживаемая ОС")
3]
" । т w v и? о s
Q t Пример использования
if____паве__ •• “__.Min,_
factory - ButtonFactoryQ
try:
• Создаем кнопку для Windows
wlnoows_button • factory.create_button('wlndows")
printffOTpwcoBica кнопки: {windows_buttoo.render(>}")
в Создаем кнопку для HacOS
eacos_button - factory.create_bvtton(’’MacOS")
print(f"Отрясовка кнопки: 'aacos.button.render()}")
• Создаем кнопку для Linux
linuxbutton factory.create_b«tton("Linux")
print(f’OTp*coeKa кнопки: {linux_button.render{)}")
f Попытка создать кнопку для неподдерживаемой ОС
unknown.button - factory.cr*ate_button("UnknownOS")
except ValueError as e:
prlnt(e)
5? Отрисовка кнопки: Кнопка Windows
Неподдерживаемая ОС
Рис. 7.30
Наблюдатель
Паттерн Observer (Наблюдатель) [89] позволяет реализовать систему уведом-
лений, где объекты могут регистрироваться на события других объектов.
class Subject:
def _ _init_ (seif):
self, observers = []
def add ooserver(self, observer):
self._observers.append(observer)
def notifyfself, message):
for oos in self.-Observers:
oos.update(message)
class Observer:
def update(self, message):
print(f"Получено сообщение: (message)")
" ----------------------------------------------------- t 4 ♦ oo о C n !
m л .- —___________=>
Q • Прчр вспмвзомми»
I ~ •*ln—
• Семи» су<*«т
«object . Subject ()
• С«МММ I TO»**
* м11_оЬм«**«е - (mi Wb*«r**rco»')
loggw^pbiervvr • logg*rt)burv*r )
• ДОМЛМЯ ч|»МД*Т»*Н «С Субмвту
«object .*dd_<b««r-w(tMll_OP»*rv*r j
«object. »Ь<,«И*птг, MK_ebserver)
tuejec t. *M_eb*erv*r< j oggw ooterver j
• <h-,>*»-*«
print ("VOt прем* j^uaww» - ..')
subject .aotl<y ('<•< тема готом (мботеР)
»д****м ай~а*е «stuaewvw»
print(*\«уммм* $H5 m*6m*»t*ju»...->
cob Jec 1 * reewe_obi«rv«r< wts_obs«rv*r)
-’•₽***«* второ* pteMMW»
print(*VCrnpWA* вторвго уевжммммм...*)
«ubJect.Mtlfyt,"Новое ы«»9» Лв***инГ)
Огарев»* 0«аи»ни...
Ем110Ь«ег-г*г; Sending •«* 11 to Bl frill >'* ГМ with «ИМ®*; Свстем* готом к ребот*1
iKSObMwpr Seeding S*tS to «TftWIlMW with »*»м«* <»ст«м сотом к р*Фот«|
Lo<f*r0b4*rv»r iofflnf MtMf*; Свствм* готом < робот*!
Умении SHS >»6м*г«м
Отрроом второго уоммм»*»*..
EMllObTorvtr; Sooding «*tii to W1*fWl*№1* 'HW “it* вм»«с»: ново* o«dw* oCmm*»mi
Logg*rQM*<r«wr: logging wsug*: ново* ввямм обмовмни*!
Рис. 7.31
В этой главе мы рассмотрели ключевые концепции ООП, их реализацию
в Python и практические примеры применения. ООП — фундаментальная па-
радигма, позволяющая эффективно решать сложные задачи и разрабатывать
надежное программное обеспечение.
Выводы
В главе детально рассмотрены ключевые принципы ООП и их реализация
в языке Python. Ниже — систематизированные выводы, объединяющие ос-
новные положения.
1. Базовые принципы ООП в Python
Инкапсуляция — механизм защиты данных и контроля доступа:
• реализуется через соглашения об именовании (_ — защищенный,__—
приватный), декораторы (©property/(©setter, геттеры/сеттеры;
• обеспечивает:
- сокрытие внутреннего состояния объекта;
- валидацию данных при изменении атрибутов;
- предотвращение некорректных операций (например, отрицатель-
ный радиус в классе Circle);
примеры: класс BankAccount с приватным атрибутом ___balance, класс
Temperature с преобразованием шкал через свойства.
Наследование — инструмент повторного использования кода:
• позволяет создавать дочерние классы на основе родительских, наследуя
атрибуты и методы;
• поддерживает:
- переопределение методов (например, speak () в классах Dog и Cat);
- множественное наследование (с учетом MRO — Method Resolution
Order);
- использование super() для вызова родительских методов;
• упрощает модификацию функционала без изменения базового кода.
Полиморфизм — гибкость взаимодействия с объектами:
• дает возможность обрабатывать объекты разных классов через единый
интерфейс;
- реализуется в Python через:
- переопределение методов в наследниках;
- duck typing (проверка наличия метода, а не типа объекта — пример
с классами Duck и Dog, реализующими quack ());
- дженерики (модуль typing) для т иповой безопасности;
- паттерны (например, «Стратегия») для динамического выбора ал-
горитмов;
• снижает связность кода и повышает универсальность функций.
Абстракция — упрощение сложности:
• фокусируется на ключевых характеристиках объекта, скрывая детали
реализации;
• реализуется через:
- абстрактные классы (модуль abc, декоратор (©abstract™ ethod, при-
мер с классом Animal);
- композицию (класс Саг включает объект Engine, а не наследует от
него);
- паттерны проектирования (Фасад, Адаптер);
• пример фасада: класс Computer упрощает взаимодействие с CPU
и Memory, скрывая низкоуровневые операции.
2. Инструменты универсальности и гибкости
Обобщенные классы и функции — работа с любыми типами данных:
• используют TypeVar и Generic (модуль typing);
• обеспечивают:
• повторное использование структур (например, класс Container|Т] для
хранения int, str и др.);
• типовую безопасность (статическая проверка типов);
• пример: Container [ int] .add( 1) и Container[str].add(«hello»).
• Duck typing — альтернатива строгим интерфейсам:
• функция работает с любым объектом, имеющим нужный метод (напри-
мер, make_it quack (animal) требует только quack ());
• повышает универсальность кода за счет проверки поведения, а не типа.
3. Паттерны проектирования
В Python реализованы проверенные решения для типовых задач:
• Singleton — гарантирует единственный экземпляр класса (пример
с instance в классе Singleton).
• Фабричный метод — создает объекты без указания их типа (класс
ButtonFactory выбирает WindowsButton в зависимости от os_type).
• Наблюдатель (Observer) — реализует систему уведомлений (класс Subject
уведомляет зарегистрированные Observer).
♦ Адаптер — адаптирует старый интерфейс к новому (класс Adapter обо-
рачивает OldSystem).
• Фасад — упрощает взаимодействие со сложными подсистемами (класс
Computer скрывает детали работы CPU и Memory).
4. Динамические возможности Python
• Язык предоставляет продвинутые механизмы для модификации пове-
дения.
• Декораторы классов (например, log_ methods) — изменяют поведение ме-
тодов.
• Метаклассы (например, Meta) — управляют созданием классов (добав-
ляют атрибут version).
* Итераторы (методы___iter_и___next_) — обеспечивают обход коллек-
ций (пример Countdown).
♦ Собственные исключения (например, NegativeBalanceError) — повыша-
ют надежность кода.
5. Специфика Python в ООП
Особенности языка, усиливающие ООП:
• отсутствие строгих интерфейсов компенсируется duck typing и дженери-
ками;
• динамическая типизация сочетается с возможностями статической про-
верки (модуль typing};
• механизмы super(), MRO, (©property упрощают реализацию принципов
ООП;
• композиция часто предпочтительнее наследования (пример: Саг содер-
жит Engine).
Итоговый вывод
• ООП в Python — это мощный инструмент для создания:
• модульного кода (через инкапсуляцию и абстракцию);
• гибких систем (благодаря полиморфизму и duck typing);
• универсальных решений (с использованием обобщенных классов);
• надежных приложений (через обработку исключений, декораторы, мета-
классы).
Ключевые преимущества:
• Читаемость — четкое разделение ответственности (классы, методы).
• Повторное использование — наследование, композиция, паттерны.
• Масштабируемость — абстракция и интерфейсы упрощают расширение
функционала.
• Безопасность — инкапсуляция и валидация защищают данные.
Понимание этих концепций позволяет проектировать системы, которые:
• легко поддерживать и тестировать;
• эффективно масштабировать;
• адаптировать к изменяющимся требованиям.
Глава 8
Работа с базами данных
в Python
Подключение к базам данных
и выполнение запросов
Python предоставляет обширный инструментарий для взаимодействия с раз-
личными системами управления базами данных (СУБД) [90]. Рассмотрим
основные подходы к подключению и выполнению запросов, используя в ка-
честве примеров SQLite (встроенная СУБД) и PostgreSQL (одна из наиболее
популярных промышленных СУБД).
Пример подключения к SQLite:
import sqlite3
conn = sqlite3.connect('example.do', check_same_thread=False)
cursor = conn.cursor()
if Создание таблицы
cursor.execute('CREATE TABLE IF NOT EXISTS users
(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)"')
# Вставка данных
cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ("Ан-
на", 28))
conn.commit() # Фиксация изменений
О Чтение данных
cursor.execute("SELECT * FROM users")
print(cursor.fetchail()) # Вывод: [(1, 'Анна', 28)]
conn.close() # Закрытие соединения
for obs in s«lf._obs«rvwrs:
obi.update(aess<ge)
class Observer:
def update(self, Message):
print(f**noay>e*M> сообщение: (Message^")
ф ieport sqlitel
conn • sq Ht«3. connect (’example.db’, check_s**e_thre*d»Fals.e)
cursor conn.cursorQ
• Создание тобличи
cursor.execute( "'CREATE TABLE IF NOT EXISTS users
(id INTEGER PRIMARY KEY, мм TEXT, age INTEGER)'")
• Встааха дак««х
c ursor.execute(“IWSERT INTO users (naae, age) VALUES (?, ("Анна", 28))
coon.coaeitO • •мхсачия иженемий
• Чтение даншх
cur*or.execute(’S£LECT • FRCH users")
print(cursor.f<tcholl()) • Ьмвод [(1, 'Анна', 28)]
conn.close() • Закрытие соединения
— ((1, Аяна', 2B)J
free sqlalchMy ieport creat*_engii»e, ColiMn, Integer, String, Sequence, ForeignKey
fro* sqlalcheery .ore iaport declarative.base, sessioneaher, relationship
Base dec1aretive_base()
Рис. 8.1
SQLite — это встроенная СУБД, что делает ее идеальным выбором для
разработки прототипов и небольших приложений. Однако для более круп-
ных и производительных систем рекомендуется использовать промышлен-
ные СУБД, такие как PostgreSQL.
ORM и SQLAlchemy: абстракция вместо SQL
ORM (Object-Relational Mapping) представляет собой технологию, позволя-
ющую работать с реляционными базами данных, используя объекты Python.
SQLAlchemy — одна из наиболее популярных ORM-библиотек для Python,
которая предоставляет широкий спектр возможностей для работы с базами
данных.
Пример модели пользователя с использованием SQLAlchemy:
from sqlalchemy import create engine, Column, Integer, String,
Sequence
from sqlalchemy.ext.declarative import deciaracive_base
from sqlalchemy.orm import sessicnmaker, relationship
Base = declarative base()
class User(Base):
tablename = 'users'
_table_args _ = {'schema': 'public'} # Опционально: указание схемы
id = Column(Integer, Sequence('user id seq'), primary_key=True)
name = Column(String(255))
age = Column(Integer)
address = Column(String(512))
posts = relationship("Post", back_populates="author") # Связь "один
ко многим"
class Post(Base):
_tablename_ = 'posts'
id = Column(Integer, Sequence('post_id_seq'), primary_key=True)
title = Column(String(255))
content = Column(String)
author_id = Column(Integer, ForeignKey('users.id'))
author = relationship("User", back_pcpulates="posts") ^Обратная связь
conn.clos* *() * Закрытие соединения
1(1, “Анна*, 28)]
Q from sqlalchewy import creete.engine, Coluen, Integer, String, Sequence, ForeignKey
from sqlalcheery.ore report declar*tive_baie, sessionaaker, reletionship
Base • declaretive_base()
class User(Base):
___tablenaae____ • ’users’
___table_args__ {’schema': 'public'} • Опфюмальмо: указание схемы
id • Column(Integer, Sequence(*useraid,,seq‘), pri»iry_key.True)
name • Coluen(String(2SS))
age • Column (Integer)
address Column(Strxng(S12))
posts reletionship(“Post*, backjwpulstes«’euthor*) « Cease “один ко многим"
class Post(Base):
___tablename__ « ’posts’
id • Colimm(Integer, Scquence('post_id_seq'), prim«ry_key»True)
title • Coluen(Str5ng(25S))
content • Column(String)
*uthor__id Colimei( Integer, ForeignKey( 'users.id"))
author relotionship(“User", back_populates»“posts") • Обратная cense
ieport sqliteJ
a Using a context manager to ensure the connection is closed automatically
with »qlite3.connect('exa^le.db*) os conn:
cursor conn.cursor()
Рис. 8.2
Плюсы использования ORM:
• Абстракция. ORM позволяет работать с базой данных, используя объ-
екты Python, что упрощает разработку и делает код более читаемым.
• Защита от SQL-инъекций. ORM автоматически экранирует параметры
запросов, предотвращая уязвимости, связанные с SQL-инъекциями.
• Переносимость, О RM позволяет легко переносить код между различ-
ными СУБД, изменяя только настройки подключения.
Обработка результатов запросов
и отображение данных
При работе с базами данных часто возникает необходимость преобразова-
ния результатов запросов в более удобный формат для дальнейшей обработ-
ки. Рассмотрим два подхода: использование встроенной функциональности
SQLite и библиотеки Pandas.
Преобразование результатов в словари
с использованием SQLite
Алгоритм создания таблицы users и выполнения запроса:
1. Импортируем модуль sqlite3.
2. Создаем соединение с базой данных example.db.
3. Создаем объект курсора для выполнения SQL-запросов.
4. Создаем таблицу users с колонками:
• id: INTEGER, PRIMARY KEY, AUTO INCREMENT.
. name; TEXT, NOT NULL.
. age: INTEGER, NOT NULL.
5. Вставляем данные в таблицу users:
• пользователь с именем Al ice и возрастом 30;
• пользователь с именем Bob и возрастом 25.
6. Сохраняем изменения с помощью метода commit ().
7. Закрываем соединение с базой данных.
8. Повторно создаем соединение с базой данных example.ab.
9. Устанавливаем row factory на sqiite3.Row для получения строк в фор-
мате словарей.
10. Создаем новый объект курсора для выполнения SQL-запросов.
11. Выполняем запрос для получения всех записей из таблицы users.
12. Извлекаем все строки результата запроса с помощью метода fetchall ().
13. Обрабатываем и выводим результаты: перебираем каждую строку
и выводим имя и возраст пользователя.
14. Закрываем соединение с базой данных.
Этот алгоритм структурирован так, чтобы последовательно описывать
действия, которые необходимо выполнить для создания таблицы и получе-
ния данных.
import sqlite3
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
# Создание таблицы users
cursor.execute('"
CREATE TAELE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER NOT NULL
)
"')
# Пример вставки данных
cursor.execute("INSERT INTO users (name, age) VALUES ('Alice', 30)")
cursor.execute("INSERT INTO users (name, age) VALUES ('Bob', 25)")
conn.commit() # Сохраняем изменения
conn.close()
import sqlite3
conn = sqlite3.connect('example.db*)
conn.row_factory = sqlite3.Row # Установка фабрики строк для возврата
словарей
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
rows = cursor.fetchall()
# Проходим по результатам и печатаем значения
for row in rows:
print(row['name'], row['age'])
conn.close()
С помощью установки фабрики строк sqlite3.Row результаты запроса
возвращаются в виде словарей, что упрощает их обработку.
----------------------------------------------------------------------------------------------------------------------------------------------------- f ♦ Z В I
© bvo< t цНи)
• using a cent*wt aanagvr to anwa tba ceerxctloa la dotod lutoewkally
with Kjllt«Jxca>i»<t{ »xa^l».db') a» wnn
cww .
• Coixiw vaftaxtai users (аобааммо IF NOT EXISTS «*а прааога^ацмм ам<а< яря поатсчжм нмуеш)
cwsor.«eewtti '
СМАТС TAtlt If NOT exists wen <
Id PttMMY MV «UIOINCMMNI.
new ttXT NOT NULL,
a«a INI НИ» MOT Mill
)
• npsBipiiii, lywcrayar w jm А*»м, чю&« «6axaia яуОяафояаияя п^я лоягоршя aanytaa
»M-i4>-,a<a<vta(*$(UCi сожт(') <<w vs*rs ымТМ n*w •
И prw,<«Ubw()|»! « •;
• Прия*» ястамп» дам»
cwrspr.MMwttCIMSECi INTO users (мм. aft) vUUES CAli<«\ *•>’}
cursor.INTO users (лам, a««) VM.UES ('Mb*, IS)')
Mnn.COwltO ’ COapArtOM «Willi II*
• Усаачока фаОряча строк дл> wiwpera слс*ар«О *>* уярОюгд ло<тутю « **"»♦•> п» танам пияЬдая
«nei.row_<*ctory • Split*).Аби
curs*r - со«*.с«гмг() • Сохдаам новый курсор после ияиенечм r«w_f*ctonr
смгмг.шеем»(*1ПССТ FMR users')
rows • Cursor. fat (МП О
• Лрожец»** ею р*1уаът*гам и гечотаам виачаимя
<or row In rows;
print(fwj "*!•*’ j. row|
— дин* JX
Alice M
too 2$
Рис. 8.3
Использование библиотеки Pandas
для анализа данных
import pandas as pd
conn = sqlite3.connects 'example.db')
df = pd.read_sql("SELECT name, age FROM users", conn)
print(df.head()) # Вывод первых пяти строк DataFrame
print(df['age']-describe()) ff Статистические характеристики возраста
tsi
. 3
сек.
Q import pandas as pd
conn = sqlite3.connect('example.db')
df = pd.read_sql("SELECT name, age FROM users”, conn)
print(df.head()) # вывод первых пяти строк DataFrame
print(df('age*].describe()) # Статистические характеристики возраста
name
0 Alice
1 Bob
count
mean
std
min
25%
59%
75%
max
Harner
age
30
25
2.090009
27.590909
3.535534
25.990909
26.250900
27.590909
28.750909
39.000000
age, dtype: float64
Рис. 8.4
Библиотека Pandas 191 ] предоставляет мощные инструменты для анализа
и обработки данных, полученных из баз данных.
Исторический экскурс: PostgreSQL vs NoSQL
Эволюция систем управления базами данных привела к появлению различ-
ных подходов, каждый из которых имеет свои преимущества и недостатки.
Рассмотрим основные различия между реляционными базами данных (на
примере PostgreSQL) и NoSQL-базами [92].
Реляционные базы данных (PostgreSQL)
Реляционные базы данных, такие как PostgreSQL, были разработаны в 1970-х
годах и с тех пор стали стандартом для хранения структурированных дан-
ных. Они основаны на концепции таблиц и связей между ними, что позволя-
ет эффективно моделировать сложные структуры данных.
Основные характеристики PostgreSQL:
• Строгая схема данных. Каждая таблица имеет строго определенную
структуру, что обеспечивает целостность данных.
• Транзакции. Поддержка ACID-транзакций (атомарность, согласован-
ность, изоляция, долговечность) обеспечивает надежность и целост-
ность данных.
• JOIN-запросы. Возможность выполнения сложных запросов с исполь-
зованием JOIN для объединения данных из нескольких таблиц.
Когда использовать PostgreSQL:
• Сложные транзакции: финансовые системы, системы управления скла-
дом.
• Строгая структура данных: приложения, требующие жесткой схемы
данных.
• JOIN-запросы: приложения, требующие сложных аналитических за-
просов.
NoSQL-базы данных
NoSQL-базы данных появились в 2000-х годах в ответ на требования масшта-
бируемости и гибкости, предъявляемые современными веб-приложениями.
Они предлагаю! различные подходы к хранению данных, включая документ-
ные, ключ-значение и колоночные модели.
Основные типы NoSQL-баз данных:
• Документные (MongoDB). Хранение данных в виде JSON-подобных
документов, что обеспечивает гибкость и масштабируемость.
• Ключ-значение (Redis). Хранение данных в виде пар «ключ-значе-
ние», что обеспечивает высокую производительность и масштабиру-
емость.
• Колоночные (Cassandra). Хранение данных в виде столбцов, что опти-
мизировано для операций записи и чтения больших объемов данных.
Преимущества NoSQL-баз данных:
• Гибкость. Возможность хранения данных с изменяемой структурой.
• Масштабируемость. Горизонтальное масштабирование позволяет
легко увеличивать производительность системы.
• Производительность. Оптимизация для операций записи и чтения
больших объемов данных.
Когда использовать NoSQL:
• Большие данные: аналитика, машинное обучение.
• Гибкие схемы данных: приложения, требующие динамического изме-
нения структуры данных.
• Высокая производительность: приложения, требующие высокой ско-
рости операций записи и чтения.
Введение в NoSQL: MongoDB на примере
MongoDB [93] — одна из наиболее популярных документных NoSQL-баз дан-
ных, которая предоставляет гибкие возможности для хранения и обработ-
ки данных. Рассмотрим основные аспекты работы с MongoDB на примере
Python.
Установка драйвера:
pip install pymongo
о pip install pymongo
* се».
5? Collecting pymongo
Downloading pymongo-4.15.0-cp312-cp312-manylinux_2_17_x86_64.eanylinux2ei4_x86_64.whl.metadata (22 kB)
Collecting dn$python<3.0.0,>«1.16.8 (from pymongo)
Downloading dnspython-2.8.0-py3-none-any.whl.inetadata (5.7 kB)
Downloading pymongo-4.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.7 HB)
----------------------------------------- 1.7/1.7 MB 23.4 MB/s eta 8:00:00
Downloading dnspython-2.8.0-py3-none-any.whl (331 kB)
-------------------------------------------- 331.1/331.1 kB 24.9 M6/s eta 0:00 00
Installing collected packages: dnspython, pymongo
Successfully installed dnspython-2.8=8 pymongo-4.15.8
Рис. 8.5
MongoDB предоставляет гибкие возможности для работы с данными, поз-
воляя хранить данные в виде JSON-подобных документов. Это делает ее иде-
альной для приложений, требующих динамической структуры данных.
Работа с базами данных — ключевой аспект разработки современных
приложений. Выбор подходящей СУБД зависит от требований конкретного
проекта. Для структурированных данных с четкими связями рекомендует-
ся использовать реляционные базы данных, такие как PostgreSQL. В случаях,
когда требуется гибкость и масштабируемость, лучше выбрать NoSQL-реше-
ния, такие как MongoDB.
ORM, например SQLAlcheiny, значительно упрощают разработку, предо-
ставляя абстракцию над SQL-запросами и обеспечивая защиту от SQL-инъ-
екций. Библиотека Pandas может быть использована для анализа данных, по-
лученных из баз данных, предоставляя мощные инструменты для обработки
и визуализации данных.
Выводы
Глава посвящена ключевым аспектам взаимодействия с базами данных
в Python, включая подключение к СУБД, выполнение запросов, исполь-
зование ORM и работу с различными типами баз данных (реляционными
и NoSQL). Рассмотрим основные выводы.
1. Python предоставляет гибкие инструменты для работы с базами дан-
ных. В языке доступны как низкоуровневые драйверы (например,
sqlite3 для SQLite, psycopg2 для PostgreSQL), так и высокоуровневые
абстракции, такие как ORM-библиотеки. Это позволяет выбирать
подход в зависимости от сложности проекта и требований к произво-
дительности.
2. SQLite подходит для прототипирования и небольших проектов. Эта
встроенная СУБД проста в использовании, не требует отдельного сер-
вера и подходит для разработки и тестирования. Однако для крупных
и высоконагруженных систем рекомендуется использовать промыш-
ленные СУБД, например PostgreSQL. geeksforgeeks.org +1.
3. ORM (Object-Relational Mapping) упрощает разработку и повышает
безопасность. Библиотеки вроде SQL Alchemy позволяют работать
с базой данных через объекты Python, а не через SQL-запросы. Это
ускоряет разработку, снижает риск ошибок, обеспечивает защиту
от SQL-иньекций и упрощает перенос кода между разными СУБД.
Однако ORM может снижать производительность в сложных сцена-
риях и требует понимания принципов работы для эффективной от-
ладки .proglib.io +2.
4. SQLAlchemy — гибкая ORM-библиотека для Python. Она поддерживает
как высокоуровневый ORM-подход, так и работу с SQL-выражениями,
что дает разработчику больше контроля над запросами. Это особенно
полезно в проектах, где требуется оптимизация сложных запросов.
5. Для обработки результатов запросов можно использовать разные
подходы. Например, с помощью sqlite3.Row в SQLite результаты за-
просов возвращаются в виде словарей, что упрощает их обработку.
Библиотека Pandas позволяет анализировать данные, полученные из
баз данных, предоставляя мощные инструменты для обработки и ви-
зуализации.
6. Выбор между реляционными и NoSQL-базами данных зависит от тре-
бований проекта.
• Реляционные базы данных (например, PostgreSQL) подходят для
структурированных данных с четкими связями, сложных транзакций,
финансовых систем, ERP-систем и бизнес-аналитики. Они обеспечи-
вают строгую согласованность данных (ACID-транзакции) и подде-
рживают сложные JOIN-запросы .geeksforgeeks.org +2.
• NoSQL-базы данных (например, MongoDB) оптимальны для больших
объемов данных, гибких схем, высокой производительности и масшта-
бируемости. Они подходят для социальных сетей, 1оТ, геоинформаци-
онных сервисов и быстро меняющихся проектов .geeksforgeeks.org +2.
7. MongoDB — популярная документная NoSQL-база данных. Для рабо-
ты с ней в Python используется драйвер pymongo. MongoDB позволяет
хранить данные в JSON-подобном формате, что удобно для приложе-
ний с динамической структурой данных .geeksforgeeks.org +2.
8. При выборе СУБД важно учитывать критерии:
• для проектов с жесткой структурой данных и сложными транзакция-
ми предпочтительны реляционные базы;
• для проектов с большими данными, высокой нагрузкой и часто меня-
ющейся структурой данных лучше подходят NoSQL-решения.
9. Современные тенденции включают гибридные решения, сочетающие
ORM и декларативный SQL, а также интеграцию с аналитическими
и распределенными СУБД.
Таким образом, работа с базами данных в Python требует выбора подходя-
щего инструментария в зависимости от специфики проекта. ORM упрощает
разработку, но для высоконагруженных систем или сложных запросов может
потребоваться переход на низкоуровневые драйверы или ручной SQL. При
выборе СУБД ключевыми факторами являются структура данных, требова-
ния к масштабируемости и согласованности.
Глава 9
Графическое
программирование
Разработка графических приложений
Альтернативные подходы в Google Colab
Если вы хотите визуализировать данные или создать пользовательский ин-
терфейс для задач в Google Colab, вот несколько альтернативных методов:
1. Использование виджетов IPython. Вы можете использовать библиоте-
ку i.pywidgets [94], чтобы создать интерактивные элементы прямо в Jupyter
Notebook или Google Colab. Например, вы можете создать кнопки, слайдеры
и другие виджеты:
import ipywidgets as widgets
from IPython.display import display
# Создаем текстовое поле
text = widgets.Text (
value*'Привет, мир!',
description*'Текст:',
disabled*False
# Создаем функцию для реагирования на изменение
def on_text_change(change):
print("Текст изменен на:", change['new'])
text.observe(on_text_change, names*'value')
# Отображаем виджет
display(text)
О ipywidgets •» widget*
‘Z сек froy IPython.display report display
• Создаем текстовое поло
text » widgets.Text(
volt*"'привет, морг,
description* 'Текст: •,
disabledeFalse
)
о Создаем функцию для реагирование на иаменание
de* on_t*xt_chonge(change):
print("Текст иаменом на:", change,'new'])
teлt,observe (on_text_cbongo, лакее*'value')
о Отображаем видке*
diepioy(text)
Рис. 9.1
2. Визуализация данных с помощью Matplotlib или Seaborn.
Вы можете создавать графики для визуализации данных:
import matplotlib.pyplot as pit
# Пример простого графика
plt.plot([l, 2, 3], [4, 5, 6])
pit.title("Пример графика")
plt.xlabel("Ось X")
plt.ylaoel("Ось Y")
plt.showO'
Q laport •atpletlib.pyploc м pit
о прммар престего графика
Plt.pletCi, 2, >), (o, », •})
pit.title("Протер графика")
Plt.KlebelC*» X")
pit.уlabel("be* v~)
plt.ahovO
Визуализация данных
Matplotlib
Matplotlib — это одна из наиболее популярных библиотек для визуализации
данных, предоставляющая широкий спектр возможностей для создания раз-
личных типов графиков и диаграмм. Это неотъемлемая часть экосистемы
Python, которая широко используется в научных исследованиях, анализе дан-
ных и разработке программною обеспечения. Установка Matplotlib осущест-
вляется через менеджер пакетов pip.
Установка Matplotlib
Сначала убедитесь, что библиотека установлена. Обычно она уже есть
в Google Colab, но, если что-то пойдет не так, вы можете установить ее следу-
ющим образом:
!pip install matplotlib
© ipip install matplotlib
... Requirement already satisfied: matplotlib in /usr/local/lib/pythons.12/dist packages (3.10.0)
Requirement already satisfied: contourpy>-i.0.i in /usr/local/Mb/python3.12/dist-packages (from matplotlib) (1.3.3)
Requirement already satisfied: cycler>-0.10 in /usr/local/lib/python3.12/dist-packages (from matplotlib) (6.12.1)
Requirement already satisfied: fonttools>-4.22.e in /usr/local/Kb/pytho<»3.12/dist-packages (from matplotlib) (4.61.1)
Requirement already satisfied: kiwisolver>-l,3.1 in /usr/local/lib/pytton3.127dist-packages (from matplotlib) (1.4.9)
Requirement already satisfied: numpy>-1.23 in /usr/local/lib/pytbon3.12/dist-packages (from matplotlib) (2.0.2)
Requirement already satisfied: packaging>-29.0 in /usr/local/lib7python3.12/di$t-packages (from matplotlib) (25.9)
Requirement already satisfied: pillow>-8 in Zusr/local/lib/python3.12/dlst-packages (from matplotlib) (11.3.0)
Requirement already satisfied: pyparsing>-2.3.1 in /usr/local/lib/python!.12/dlst-packages (from matplotlib) (3.3.1)
Requirement already satisfied: python-dateutil>-2.7 in /usr/local/lib/python3.12/dist-packages (from matplotlib) (2.9.9.post9)
Requirement already satisfied: six>-1.5 in /usr/local/lib/python3.12/dist-packages (from python-dateutil>-2.7->matplotlib) (1.17,0)
Q import eatplotlib.pyplot as pit
import пиару as np
• Генерация данных
np.random.seed(42)
x - np.iinspace<e, 10, iw)
у • np.sin(x) ♦ np.random.normal(0, 0.1, x.shape)
• 1. Простая линейная диаграмма
pit.figure(figsize-(10, 5))
plt.plot(x, y, label* *'Синус*, color-’blve', linewidth«2)
pit.title(‘Простая линейная диаграмма*)
Рис. 9.3
Ниже приведен код, демонстрирующий различные виды графиков и их
настройки, которые вы можете запустить в Google Colab:
import matplotlib.pyplot as pit
import numpy as np
# Генерация данных
np.random.seed(42)
x = np.linspace(0, 10, 100)
у = np.sin(x) + np.ranoom.normal(0, 0.1, x.shape)
# 1. Простая линейная диаграмма
pit.figure(figsize=(10, 5))
pit.plot(x, y, label='Синус', color='blue', linewidth=2)
pit.title('Простая линейная диаграмма')
plt.xlabel('x')
plt.ylabel('y')
pit.legend ()
pit.grid»
pit.shew()
# 2. Scatter Plot (точечная диаграмма)
plt.figure(figsize-(10, 5))
pit.scatter(x, y, color='red', alpha=0.5)
pit.title('Точечная диаграмма')
plt.xlabel('x')
plt.ylabel('y')
plt.gridO
pit.show()
4 3. Гистограмма
data = np.random.randn(1009)
plt.figure(figsize=(10, 5))
pit.hist(data, bins=30, co)or-'purple', alpha-2.7)
pit.title('Гистограмма')
pit.xlabel('Значения')
pit.ylabel('Частота')
plt.gridO
pit.show()
# 4. Бар-график
categories = ['А', 'В', 'С', 'D']
values = [3, 7, 5, 10]
pit.figure(figsize= (10, 5))
pit.bar(categories, values, colors'orange')
pit.title('Бар-график')
pit.xlabel('Категории')
plt.ylabel('Значения')
plt.grid(axis=' y')
pit.show()
if 5. Столбиковая диаграмма
labels = ['Серия 1', 'Серия 2', 'Серия 3']
menjneans = [20, 35, 30]
womenjneans = [25, 32, 34]
# Изменение имени переменной х
х labels = np.arange(len(labels)) # метки на оси х
width = 0.35 # пирина столбца
plt.figure(figsize=(10, 5))
rectsl = pit.bar(х labels - width/2, men means, width, label3'Мужчины',
color='blue')
rects2 = pit.bar (x labels + width/2, womenjneans, width, label3*Женщины',
color='pink')
plt.ylabel('Результаты')
plt.titie('Сравнение результатов мужчин и женщин')
plt.xticksfx labels, labels)
pit.legend()
pit.grid(axis3'y')
pit.show()
# 6. Круговая диаграмма
sizes = [30, 10, 20, 40]
labels = ['А', 'В', 'C', 'D']
plt.figure(figsize=(10, 5))
pit.pie(sizes, labels=labels, autopct='%l.lf%%', startangle=90)
pit.axis('equal') fr Равные оси, чтобы круг выглядел правильно
pit.title('Круговая диаграмма')
plt.showO
# 7. Подписи на графиках
pit.figure(figsize^(10, 5))
pit.plot(x, y, laoel='Синус', color='blue', linewidth=2)
pit.title('Подписи на графиках')
plt.xlabel('x')
plt.ylabel('y')
# Добавление аннотаций
pit. annotate ('Максимум', xy=(x[np.агатах (у) ], y.maxO), xytext=(x’np.
argmax(y) ], y.max() + 0.5),
arrowprops^dict(facecolor='black', arrowstyle='->'))
pit.legend()
plt.gridO
plt.showO
# 8. Подграфики
fig, axs = pit.subplots(2, 2, figsize=(10, 10))
axs[0, 0].plot(x, y, color='blue')
axs[0, 0].set_title(‘График 1')
axs[0, 1].scatter(x, y, color-'red')
axs[0, 1].set_title('График 2')
axs[l, 0].hist(data, bins=30, color='purple', alpha=0.7)
axs[1, 0].set_title('Гистограмма')
axs[l, 1].oar(categories, values, color='orange')
axs[l, lj.set title('Бар-график')
# Связь друг с другом
pit.tight_layout()
plt.showO
и lapart matplotlib.pyplot as pit
iaport ливру as np
* Генерация даидос
np.random.seed(42)
ж - np.1inspace(в, 10, 100)
у np.sin(x) + np.random.narmal(0, 0.1, x.shape)
a 1. npo< i«₽j линейная - диаграмм-
pit.figure(figslze-,10, 5))
plt.plot(x, y, label-’Синус', color-’blv- . linewidth-’.
pit.title(‘Простая линейная диаграмма’)
plt.xlabel(’x')
plt.ylabel('у')
plt.legendO.
plt.gridO
plt.showf)
• 2. Scatter Plot (точечная диаграмма)
pit.figure(figsize-(10, 5))
pit.scatter(x, y, color-°red', alpha-0.5)
pit.tltle(’Точечная диаграмма')
plt.xlabelCx)
plt.ylabel(’y')
plt.gridO
plt-showO
• 3. Гистограмма
data • np.randca.randn(1000)
plt.figure(figsize-(10, S))
pit-hist(data, bins-зе, color-'purple’, alpha-0.7)
pit.title('Гистограмма')
pit-«label('Значения')
plt.ylabel(’Частота’)
plt.gridO
plt.show()
» 4. Бар-график
Рис. 9.4
gj laport matplotlib.pyplot as pit
Import ливру as np
• Генерация данных
np. random. seed (42)
x - np. Hnspace(0, 10, 100)
у - np.sin(x) ♦ np.random.normal(0, 0.1, x.shape)
» 1. Простая линейная диаграмма
plt.figure(figsize-(10, 5))
plt.plot(x, y, label-'Синус', color-'blue', llnewidth-2)
pit.title('Простая линейная днаграмма’)
pit.xlabel('x')
plt.ylabel('у')
plt-legendO
plt.gridO
plt.showO
• -2. Scatter-Plot*{точечная-дмтгртнм^"
pit.figure(figsize-(10, 5))
pit.scatter(x, y, color- red', alpha-и sj
pit.title('Точечная диаграмм
plt.xlabel('x’)
₽lt.ylatwl(-y'>
pit »rld(i
plt.shovO
• 3. Гистограмма
data • np.random.randn(1000)
pit.figure(figsize-(10, S))
pit.hist(data, bins-ЗО, color-’purple’, alpha-0.7)
pit.title('Гистограмма')
plt.xlabel('Значения')
plt.ylabel('Частота')
plt.gridO
>вать ® О (9 : X
I « ч. мр-|рермк
t 3. Гмстогрэмма
aata • пр.гагхю«.гапап(100в)
plt.figure(figsize-(10. 5))
plt.hist(data, bins-30, color* purple , alpha-0 7)
pit.title('Гистограмма')
plt.xlabel('Значения')
plt.ylabel('Частота')
plt.grld()
plt.$how()
a 4. Бар-график
categories - (’A', 'S', 'C, ’O’J
values * (3, 7, 5, 10]
plt.figure(figsize-(10, 5))
pit.bar(categories, values, color-’orange’)
pit.tltle(‘Gap»график’)
pit.xlabel('Категории')
pl t.у1abe1('Значения’)
plt.grid(axls-’y')
pit.show()
a 5. Столбиковая диаграмма
labels • (’Серия Г, 'серия 2’, серил 3’]
еп_аевп5 - (20, 35, 30]
wouen.ueans - (25, Э2, 34]
• иамемемне имени переменной х
x_labels - np.arange(len(labels)) w метки на оси х
widen • 0.35 е ширина столбца
plt.figure(figsize-(10, 5))
rectsl • pit.bar(x_labels • width/2, aen_weans, width, label-'Мужчины', color-'blue')
rects2 - plt.bar(x_labels + width/2, woeenaeans, width, label-'Кенииw', color-'pink')
pit.уlabel(‘Результаты’)
pit.title('Сравнение результатов мужчин и жемщчм')
pit,xticks(x_labels, labels)
Рис. 9.6
• 3. Гистограмма
data • пр.randoa.randл(1000)
plt.figure(figsize-(10, 5))
pit.hist(data, bln$-30, color-'purple', alpha-0 7)
plt.title('Гистограмма')
pit.xlabel('Значения')
plt.ylabel('частота')
plt.grid()
plt.showO
* •4.*fop-график
categories - (’A’, ’O']
values - [3, 7, S, 10]
pit.Гigure(figsize-(10, 5))
plt.bar(categories, values, color-'orange I
pit.title(’Бар-график')
pit.xlabelf'Категории')
plt.ylabel('Значения*)J
pit.grid(axis-'y')
plt.show()
• 5. Столбиковая диаграмма
labels - (’Серия V, 'Серия 2’, Серия 3']
•enoeans • [20, 35, 30]
ншвеп_иеап$ - [2S, 32, 34]
» Изменение имени переменной х
x_labels - пр.arange(len(labels)) » метки на оси х
width - 0.35 в аирина столбца
pit.figure(figsize-(10, $))
rectsl - pit,bar(x_labels - width/2, меп_ие*п$, width, label-'Мужчины', color-'blue')
rects2 - plt.bar(x_labels ♦ width/2, wonen_eeans, width, label-'Хенцины', color-’pink’)
pit.ylabel(’Результаты’)
pit.title('Сравнение результатов мужчин и женами')
pit.xticks(x_labels, labels)
pit.shOwo
5. Столбиковая диаграмма
labels ['Серия 1*, ’Серия 7" f "Серил 3'J
en.neans - [20, 35, зф]
woeen_»eans - [25» 32, 34]
# Изменение имени переменной х
x.labels - пр.arange(len(labels)) 9 метки на оси х
width - 0.35 9 мирина столбца
pit.figure(figslze-(10, 5))
rectsl plt.bar(x_labels - width/2, aen_aeans, width, label-"Мужчины*, color-‘blue")
rects2 - plt.bar(x_labels ♦ width/2, woeen_»eans, width, label-'Жеманны*, color-'pink')
pit.уlabel("Результаты*)
pit.tltle("Сравнение результатов мужчин и жен»<м')
pit.xticks(x_labels, labels)
pit.legend()
plt.grid(axls-*y')
plt.show()
9 6. Круговая диаграмма
sizes - (30, Ie, 26, 40]
labels - ['A*, "B", "C, O’]
pit.figure(figsize-(10, 5))
plt.pie(sizes, labels-labels, autopct-'Xl.lfSK', startangle-96)
plt.axis("equal') « Равные оси, чтобы круг выглядел правильно
pit.tit 1е("Круговая диаграявча)
plt.ShowO
9 7. Подписи на графиках
pit.figure(figsize-(10, 5))
plt.plot(x, у, label-’Синус’, color-'blue", llnewidth-2)
Y J- Редактироеагч ® О (9 X
plt.ylabel('y')
Рис. 9.8, 9.9
pit.snowи
• 5. Столбиковая диаграмма
labels • ("Серия 1", "Серия 2', "Серия 3"]
•eneeans - (20, 35, 30]
woeien_eeans [25, 32, 34]
В Изменение имени переменной х
x_labels - пр.arange(len(labels)) а метки на оси х
width • 0.35 9 вирина столбца
plt.figure(figslze-(ie, 5))
rectsl - plt.bar(x_labels - width/2, меп_иеап$, width, label-"Мужчины", color-"blue")
rects2 • plt.bar(x_labels + width/2, wo«en_eeans, width, label-’хемжины', color-’pink")
pit.уlabel("Результаты")
pit.title("Сравнение результатов мужчин и жен»<н*)
plt.xticks(x_labels, labels)
plt.legend()
plt.grid(axis-"y")
plt.shew()
Й 6. Круговая диаграмма
sizes - [30, 10, 20, 40]
labels - ("А", В", "C, 'O’f
pit.figure(figsize-(10, S))
pit.pie(sizes, labels-labels, autopct- "Xl.lfXX", startangle-SRs
plt.axis('equal') в Равные оси, чтобы круг•выглядел•праенлымо
pit.tit1е(‘Круговая диаграмма")
plt.show()
• 7. Подписи на графиках
pit.figure(figsize-(10, 5))
plt.plot(x, у, label-"Синус", color-"blue", linewidth-2)
pit.title("Подписи на графиках")
plt.xlabel("x")
plt.ylabel("y")
plt.axis('equal*} • Равные оси, чтобы круг выглядел правильно
pit .tit1е(’Круговая диаграмма')
pit. s!mm( )
»-1. юдлнсн на графиках
plt.figure(figsize-(19, s )
plt.plot(x, у, label-'Синусcolor-‘blue, linewidth-<
pit.tItle('Подписи на графиках’)
plt.xlabel(’x’)
plt.ylabel(’у*)
* Добавление аннотаций
pit.a«notate('Максимум', xy-(xlnp.argmax(y)], y.*ax()), xytext-(x[np.arg«ax(y)J, y.«ax() ♦ 0.5)
arrowprops-aict(facecolor-'black', arrowstyle-'->'))
pit.legend()
plt.gridO
plt.show()
в 8. Подграфики
fig, axs pit.subplots(2, 2, figsize-(19, 19))
ax$(0, 9].plot(x, y, color-’blue')
axs[0, 0] .set_t i tie (Трафик 1’)
ax$[e, l].scatt»r(x, y, color-red’)
axs[e, i).set_title( Трафик 2‘)
axs[l, 9].hist(data, bins-30, color-’purple*, alpha-9.7)
axs[l, 0],set_titie('Гистограмма')
axs[l, 1).bar(categories, values, color-'orange*)
axsfl, i].set_title('Бар-график)
• Селаь друг с другом
pit.tight_layout()
plt.show()
Рис. 9.11
arrowprops-dlet(facecolor-’black °, arrowstyle-’->'))
pit .legendO
plt.gridO
plt.sbowO
»'в-7ЯЙГЙЙЙ* ’ __ _______
fig, axs - pit.subplots(2, 2, figsize- 10. !&]
axs[0, 0].plot(x, y, color-’blue))
axs[9, О].set.title(’График 1')
axs[6, 1].scatter(x, y, color-'rJHB
axs(0, l].set_title(Трафик 2')
axs[l, 0].hist(data. blns-30, color-*purple', alpha»-,7i
axs[l, 9].set_title(’Гистограмма’)
axs[i, i].bar(categories, values, color-'orange ’
axs(l, l].set_4tle(*bap rpa4nK^|
а Связь друг с другом
pit. tight_„iayout ()
plt.sbowO
Рис. 9.12
График 1
График 2
Гистограмма
Ьар график
Точечная диаграмма
Бар-график
Гистограмма
Простая линейная диаграмма
'"\Л
Круговая диаграмма
i III
I <*»*• I J с
>.••
2
.»
Максимум
Подписи на графиках
:Av"\
Простая линейная диаграмма pit.figure(figsize=(10, 5)) pit.plot(х, у, label='Синус', coior='blue', linewidth=2) pit.title(’Простая линейная диаграмма') plt.xlaoel(’x') plt.ylabei(’y') pit.legend() pit.grid() plt.showO Создаем линейный график, который показывает изменение функции синуса с добавлением некоторого гауссовского шума. х — это значения от 0 до 10, на которых рассчитывается синус. у — это значения синуса с добавленным случайным шумом для наглядности Указываем заголовок графика, подписи для осей и легенду для обозначения линии
Точечная диаграмма pit.figure(figsize=(10, 5)) pit.scatter(x, y, color='red', alpha=0.5) plt.titie(’Точечная диаграмма') plt.xlabel(’x') plt.ylabei(’y') pit.grid» plt.showO Создаем диаг рамму, где каждое значение у отображается как точка на графике с со- ответствующим значением х. Этот график позволяет видеть разброс данных и их распределение
Гистограмма data = np. random, rar.cn (1000) pit.figure(figsize=(lC, 5)) pit.hist(data, bins=30, color-'purple', alpha=0.7) pit.title(’Гистограмма') plt.xlabel(’Значения') plt.ylabei(’Частота') clt.gridO plt.showO Гистограмма показывает распределение случайных данных, сгенерированных с помощью нормального распределения. На графике по оси х отображаются значе- ния, а по оси у — количество выбросов в каждом интервале (частота)
Бар-график categories = ['А', ’В', ’C', ’2'1 values = (3, 7, 5, 10] plt.figure(figsize»(10, 5)) pit.bar(categories, values, color='orange') pit.title (’Бар-график') plt.xlabel(’Категории') pit.ylabel(’Значения') plt.grid(axis='y') plt.showO Ьар-график визуализирует сравнение количества значений по категориям. Каждая категория (от А до D) показывает, сколько единиц ей соответствует
Столбиковая диаграмма labels = [’Серия 1', ’Серия 2', ’Серия 3'1 menjneans = [20, 35, 30] womenjneans = [25, 32, 34] x_ labels = r.p.arange (len (labels)) * метки на оси x width = 3.35 » шрина столбца plt.figure(fiasize=(10, 5)) rectsl = pit.oar(x_labels - width/2, men means, width, label='Мужчины', color='blue') Эта диаграмма позволяет сравнивать два набора данных по категориям (мужчины и женщины) для каждой из трех серий. Столбики располагаются рядом для каж- дого набора данных, что позволяет легко сопоставлять значения
rects2 = pit.bar(x_iabels + width/2, wcmenjneans, width, label®'Женщины', color®'pink') plt.ylabel('Результаты') plt.title)'Сравнение результатов мужчин и женщин') plt.xticks(x_labels, labels) pit.legend() plt.grid(axis='y') pit.show ()
Круговая диаграмма sizes = [3C, 1), 20, 4G) labels = ['А', ’В', ’C', 'D'] plt.figure(figsize=(lC, 5)) plt.pie(sizes, labels=labels, autopct='%l.lf%V, startangle=90) pit.axist'equal') # Равные оси, чтобы круг выглядел правильно pit.title{'Круговая диаграмма') pit.show () Используем круговую диаграмму для демонстрации долей, которые составляют различные категории Каждая секция диаграммы показывает процент от общего количества
Подписи на графиках plt.figure(figsize=(lC, 5)) pit.plot(х, у, label®'Синус', color='blue', linewidth=2) plt.title)'Подписи на графиках') plt.xlabel('x') plt.ylabel('у') # Добавление аннотаций pit.annotate)'Максимум', ху=(х(пр. arqrnax(y) ], у.пах()), xytext=(x[np. argmax(y)], у.max)) + 0.5), arrzwprops=dict(facecolor®'black', arrowstyle®'->')) pit.legend)) pit.grid)) pit.show)) На этом графике мы добавляем аннота- цию, которая указывает точку максимума. Это полезно, когда необходимо акцен- тировать внимание на определенных данных
Подграфики fig, axs = pit.subplots(2, 2, figsize® (10, 10)) axs'O, 0].plot(x, y, color='blue') axs[0, 0] .set title ('График Г) axs[0, 1].scatter(x, y, color®'red') axs)0, 1].set_title('График 2') axs(l, 0].hist(data, bins=30, color®'purple', alpha=C.7) axs(l, 0].set_title('Гистограмма') axs[l, 1].bar(categories, values, color®'orange') axs(l, IJ.set title(’Бар-график') « Связь друг с другом pit.tight-layout() pit.show() Создаем набор подграфиков (2x2), где каждый подграфик представляет отде- льный график, который мы рассматрива- ли ранее. Это удобно для одновременно- го сравнения различных типов графиков. Использование pit. tight_ layout () позво- ляет избежать наложения подграфиков
Библиотека Matplotlib обладает множеством возможностей для создания
более продвинутых и настраиваемых графиков, Давайте рассмотрим не-
сколько дополнительных функций, которые могут улучшить визуализацию
данных.
1. Настройка осей (логарифмическая шкала):
f Логарифмическая шкала
х = пр.linspace(1, 100, 400)
у = пр.log(х)
plt.figure(figsize=(10, 5))
plt.plotlx, у)
plt.xscale('leg')
pit.title('Логарифмическая шкала на оси х')
pit.xlabel('Логарифм х')
plt.ylabei('у')
plt.gridf)
plt.showO
ф огарифмическая мкала
х • np.linsp*ce(l, lee, 40в)
у - np.log(x)
plt.figure(figsize«(10, S>)
plt,plot(x, y)
plt.xscale(’log’)
pit.tltle('Логарифмическая скала на оси х')
pit.xlabel('Логарифм х‘)
plt.ylabel('y')
plt.grid()
pltshowj
Применение логарифмической шкалы позволяет лучше визуализировать
данные, которые охватывают несколько порядков величины.
2. Несколько рисунков (Multiple Figures):
for i in range(3):
pit.figured
pit.plot(np.random.rand(10), np.random.rand(10), ’o')
pit.title(f'График {i+1}')
pit.show()
o for 1 in range(3):
plt.figure()
plt.plot(np randoe.rand(lO), np. randoei. r and i, 10), ’o’)
pit.График (1*1}*)
plt.show()
График 1
0.8 ------------------------------------------------------------------
0.7 ’
0.6 - • e
в •
0.5 - e
0Л • e •
0.3 •
0.2
0.1
0.0 _____,______,_______,_____,______r_________,______,_______,_______,
0.1 0.2 0-3 0.4 0.5 0.6 0.7 08 09
Рис. 9.15
График 2
Рис. 9.16
<—--------------,--------»------>-------
0.0 0.2 0.4 0.6 0.8 1,0
Г рафик 3
1.0 ---------------------------------------
0.8 •
0.6
0.4 •
0.2
о.о А----1------1-----1----->------f-----г-
од 0.2 о.з ад as о.б а?
plt.figura(fig* *izt-(10, 5))
pit.plot(х, у, label-‘Синус', color-°blue‘, linewidth-2)
pit лitl<(’простая линейная диаграмма’)
plt.xlabel(’x’)
pit.уlabel(*у‘)
pit.legend!)
ph.grldu
• Сохранение графика
pit.savefig('siflple_plot.png', dp1-300)
plt.show()
Рис. 9.17
Создание нескольких отдельных фшур в цикле позволяет генерировать
несколько графиков с разными данными.
3. Сохранение графиков:
pit.figure(figsize-(10, 5))
pit.plot(х, у, label-'Синус', color='blue', linewidth=2)
plt.title('Простая линейная диаграмма')
plt.xlabel('x')
plt.ylabel('y')
pit.legend()
pit.grid()
# Сохранение графика
plt.savefig('simplejolot.png', dpi=300)
pit.show()
Видим, что график был сохранен в файле < simplejolot.png >.
Q pit,figureffigslxe-(10, 5))
plt.plot(x, у, label-‘Синус \ color-’blue* 4, lioewidth-2)
pit,title('Простая линейная диаграмма')
plt.xlabel(*x*)
plt.ylabel(y')
pit.legend()
plt.grido
» Сохранение графика
pit.savefigCsteple_plot.png', dpi-300)
plt.showO
Рис. 9.18
Метод savefig!) позволяет сохранять графики в различных форматах
(PNG, JPG, SVG и других) с заданным разрешением (например, по умолча-
нию 300 точек на дюйм).
4. Настройка цвета и стиля линий:
plt.figure(figsize=(19, 5))
plt.plot(x, у, label='Синус', linestyle-', color='blue', linewidth=2)
plt.plot(x, np.cos(x), label='Косинус', linestyle=':', color='red',
linewidth=2)
pit.title('Синус и Косинус')
plt.xlabel('x')
plt.ylabei('y')
pit.legend!)
plt.grido
pit.show()
Q pit.flgurefflgslze-(ie« 5))
plt.plotfx, y, label-’Синус’, linestyle-, color-’blue*, llnewldth-2)
plt.plot(x, np.cos(x), label-’Косинусline&tyle-’:color-*r«d*, linewidth-2)
plt.tltle('CMHyc н Косинус")
plt.xlobel('x')
plt.ylabel(’y*)
pit.legendО
plt.gridO
plt.showf)
Рис. 9.19
Можно настраивать не только цвет линий, но и их стиль (пунктирные
и сплошные). Это помогает лучше различать несколько линий на одном гра-
фике.
5. Графики сданными на карте (Heatmap):
data = np.random.rand(10, 10)
plt.figure(figsize=(8, 6))
pit.imshow(data, стар-'hot', interpolation^nearest')
pit.colorbar ()
pit.title('Тепловая карта')
pit.show()
data • лр.randoe.rand(10, 1®)
plt,figure(figslze»(8, 6))
pit,ia»haw(data, ceap-'hct", intcrpolatlon-1nearest")
pit.colorbar()
pit.title("Тепловая карта’)
pit.shgw()
x np.«range(9, 2 * np.pi, 0.1)
yl • np.sin(x)
yl np.cos(x)
Рис. 9.20
Тепловые карты используются для визуализации двумерных данных, где
цвет и яркость представляют значения.
6. График с заполнением области:
х = пр.агапсе(С, 2 * np.pi, 0.1)
yl = np.sin(x)
у 2 = пр.cos(х)
plt.figure(figsize=(10, 5))
pit.plot(x, yl, label='Синус', cclor='blue')
pit.plot(x, y2, label='Косинус', color«’red')
pit.fill^between(x, yl, y2, where=(yl > y2), facecolor='lightblue',
alpha=0.5, label='Синус > Косинус')
pit.title('Заполнение области')
plt.xlabel('x')
plt.ylabel('y')
pit.legend!)
pit.grid!)
pit.show()
0 к • пр,4г»лфе(е, 2 • np.pl, ел)
yl np.sin(x)
у2 • пр.cos(х)
plt.fIgure(figsl:e»(ie, 5))
plt.plotfx, yi, label"'C»iyc', color*'blue')
pit.plot(x, y2, label»’Косинус', color»'red’)
pit.fill_between(x, yl, y2, where*(yl > y2), facecolor*'Hghtblue’, elphe-0 5, label*'Синус > Косинус')
pIt,title('Заполнение области’)
pit-xlabel(‘x')
plt.ylobcl(‘y")
pit.legend()
plt.grido
Рис. 9.21
Функция fill_between () позволяет заполнять область между двумя лини-
ями на графике. Это полезно для визуализации разности между данными.
7. Установка аннотаций и текста на графиках
х = np.linspace(G, 10, 130)
у = пр.sin(х)
pit.figure(figsize=(10, 5))
pit.plot(х, у)
pit.title('График с аннотациями')
plt.xlabel('х')
plt.ylabei('у')
# Добавление аннотаций
pit.annotate('Вершина', xy=(np.pi / 2, 1), xytext=(np.pi / 2, 1.5),
arrowprops=dict(facecclor='black', arrowstyle='->'))
plt.text(l, С.5, 'Текст на графике', fon.tsize=12, color='green')
plt.grido
pit.show()
0 х - np. 1 ln$.p*ce(e, la, tee)
у • np.sin(x)
pit.figure(figsize»(10, 5))
plt.plot(x, у)
pit .title С Гр*$Ч»Ж с «ММОТАЦИПМК ’)
plt.xl*bel(‘x')
plt.yUtol(’y')
» Добавление «ммотеияй
pit.annotate('Веркина*, xy»t’np.pi / 2, 1), xytext*np.pi / 2, l.S),
arrowpropsMilct(facecolor»'black', arrowstyle"*>*))
plt.text(l, в.5, ’Текст на графике’, fontsize"12, color»°green')
plt.gridO
pit.showО
Рис. 9.22
Метод annotate () позволяет добавлять стрелки и пояснения в конкретные
точки графика, а функция text() добавляет произвольный текст в другую
часть графика.
8. Статистические графики (Boxplot):
data = [np.random.normal(0, std, 100) for std in range(1, 4)]
plt.figure(figsize=(10, 5))
pit.bcxplot(data, vert=True, patch_artist=True)
pit.title('Boxplot')
plt.xlabel('Группы')
plt.ylabel('Значения')
plt.xticks([1, 2, 3], ('Группа 1', 'Группа 2', 'Группа 3'])
pit.grid()
pit.show ()
<0 d*t« • [г»р. г*лдс*.гк>г»|*] 0, Std, 1001 for Std in r«ng<l, 4 )
pit.figure(figsize«(10, S))
pit .boxplot(dat*> vert«True, p*tch_«rtiit«True)
plt.title(‘Boxplot*)
pit .xl4bel(*rpymw*)
pit .ylabel( * 3«*ме»«м» •)
pit.xtick>([l, 2, 3], [’Групп* Г, ’Группа 2‘, ‘Групп* 3’])
plt.grld()
plt.show()
Группы
Рис. 9.23
Boxplot (ящик с усами) визуализирует распределение данных, а также во-
мо1 аст видеть медиану, квартили и выбросы.
9. Настройка осей и меток:
х = np.linspace(O, 10, 100)
у = пр.ехр(х)
pit.figure(figsize=(10, 5))
plt.plot(x, у)
pit.title('Настройка ссей')
plt.xlabel('x')
plt.ylabel('y')
# Установим логарифмическую шкалу для оси у
plt.yscale('lcg')
pit.grid()
pit.show()
О х • пр.Мп*р«сс(е, le, ioe)
у - np.expfxj
pit.fIgure(figslze«(lG, S))
pit.plot(x, y)
pit.titlef‘Настройка осей')
plt.xlabel^’x‘)
pH
а Установим аогарифмикческу» exany дли оси у
plt.yscale(‘log*)
plt.grido
plt.showO
Рис. 9.24
Мы изменили шкалу на оси у на логарифмическую для лучшего отображе-
ния экспоненциального роста.
Запуск в Google Colab
Объедините указанный выше код в ячейках Google Colab, чтобы увидеть
расширенные возможности Matplotlib в действии. Можно запустить каждый
пример отдельно и посмотреть, как они настраивают различные виды гра-
фиков.
Seaborn — расширенные возможности
визуализации
Seaborn [95] — это библиотека, построенная на основе Matplotlib, которая пре-
доставляет более продвинутые возможности для визуализации данных. Она
упрощает процесс создания эстетически привлекательных и информативных
графиков, используя статистические методы для улучшения представления
данных. Установка Seaborn осуществляется через менеджер пакетов pip.
Этап 1. Установка библиотеки seaborn
!pip install seaborn
gender’: пр.random.choice([‘male’, ‘feeale’J, siz«"n* *M_students),
‘age* i np. random. r*r»d int (13, 22, size«mjm_students)
)
0 pip install stabom
••• Requirement already satisfied! seaborn in /usr/local/llb/pytiwn3.12/dist-peckagcs (0.13.2)
Requirement already satisfied: nmmpyt-l.24.0,>>l.2b in /usr/lucal/llb/python).12/dist-package» (free seaborn) (2-9.2)
Requirement already satisfied: pandas>«1.2 in /usr/local/lib/python).12/dist-packages (from seaborn) (2.2.2)
Requirement already satisfied: «atplotlib!-3.6.i,>•).4 in /usr/local/lib/python).12/dist-package» (from seaborn) (3-19.0)
Requirement already satisfied: contourpy>-1.0.1 1л /usr/local/lib/pychan3.12/dist-packages (from matplotlib!-3.6.1,>-3.4->9caborn) (1.3.3)
Requirement already satisfied: cycler>>0.10 in /usr/locel/llb/pythcm).12/dist-packages (from m0tplotlib!>3.6.1,>>3.4->$eabom) (0.12.1)
Requirement already satisfied: fonttoois>*4.22.e in /utr/local/lib/pythons.12/41st-packages (froo matplotlib!").6.l(>"3.4->$eaborn) (4.61.1)
Requirement already satisfied: kiwisolver>-l.3.1 in /vsr/l<xal/lib/python3« 12/dlst-packages (from matplotlib!"J.6.1,>"3,4->s«abom) (1,4.9)
Requirement already satisfied: p»ckaglng>-20,b tn /иаг/local/1ib/pytbon).12/dist-packages (from matplot1ib!«3.6.1,>>3.4->seaborn) (25.9)
Requirement already satisfied: pillou>"S in /msr/local/lib/python).12/dist-packages (from matplotlib!").4.!,>•).4->seaborn) (11.3.0)
Requirement already satisfied: pyparslng>-2.3-1 in /usr/local/llb/pjrthon3.12/dist-packages (from matplotlib!-3.6.i,>-3.4->seaborn) (3.3.1)
Requirement already satisfied: python-dateutil>-2.7 in /usr/local/lib/pytbon3.12/dlst-packages (from matplotllbl-3.6.1,>-3.4->seaborn) (2.9.0.postd)
Requirement already satisfied: pytг>"2020.1 in /usr/local/lib/python).12/dist-packages (from pandas >!. 2->seabom) (2023.2)
Requirement already satisfied: tzdata>>2022.7 in /usr/Iocal/lib/pytbon3.12/dist-packages (from pandas>-1.2 >seaborn) (2025.3)
Requirement already satisfied: six>«1.9 in /usr/local/lib/python).12/dist-packages (from python-dateutil>>2.7->matplotlib!>3.0.!,>).4->s«aborn) (1.17.0)
import seaborn as sns
import pandas as pd
a Convert the ’data’ dictionary to a Datafram* named 'students_df’ as required by sns.scatterplpt
students_df - pd.Dataframe(data)
pit,figure(figsize"(19, 5))
sns.scatterplot(data-studentsdf, x«’mathscore', y"*reading_score", hue-'gender', style*'gender*, $-100)
plt.tltle(‘Рассеанте баллов no матеватике и чтепав')
plt.xlabel ('Балм по математике )
plt.ylabel('Балм по мтепма')
plt.gridO
plt.ShOmO
Рассеяние баллов по математике и чтению
Рис. 9.25
Этап 2. Импортирование библиотек в Python. Это необходимый шаг
перед тем, как начать использовать функционал. Давайте рассмотрим бо-
лее подробно, зачем именно мы импортируем такие библиотеки, как Pandas,
NumPy, Seaborn и Matplotlib, и какие преимущества они нам приносят.
Зачем импортировать библиотеки:
1. Pandas (import pandas as pd):
• Удобство работы с данными. Pandas предоставляет структуры данных,
например DataFrame и Series, которые делают работу с табличными
данными интуитивно понятной и удобной. Вся обработка и манипуля-
ция данными, такие как фильтрация, агрегирование и предваритель-
ная обработка, значительно упрощаются.
• Импорт и экспорт данных. Pandas позволяет легко загружать дан-
ные из различных источников, таких как CSV, Excel и SQL-базы дан-
ных, а также экспортировать обработанные данные обратно в эти
форматы.
• Функциональные возможности анализа. Pandas предлагает множество
встроенных функций для анализа данных, такие как вычисление ста-
тистик, создание сводных таблиц и агрегация.
2. NumPy (import numpy as np):
• Векторные операции. NumPy позволяет выполнять операции над мас-
сивами быстрее и эффективнее, чем стандартные списки Python. Он
реализует векторизацию, что делает вычисления над большими набо-
рами данных более производительными.
- Случайные числа. NumPy включает функции для генерации случайных
чисел, что очень полезно при создании тестовых данных или модели-
ровании.
• Математические функции. NumPy предоставляет богатый набор ма-
тематических функций для работы с массивами и матрицами, что по-
лезно для выполнения сложных вычислений и анализа.
3. Seaborn (import seaborn as sns):
• Работа с визуализацией. Seaborn построена на основе Matplotlib и обес-
печивает более высокоуровневый, удобный интерфейс для создания
статических, а также сложных визуализаций. Она позволяет быстро
создавать привлекательные графики с минимальными усилиями.
• Статистическая визуализация. Seaborn имеет функции, которые поз-
воляют визуализировать данные с учетом статистических свойств, на-
пример показывать доверительные интервалы или наносить регресси-
онную линию на точечный график.
* Темы и стили. Seaborn предоставляет возможности для настройки вне-
шнего вида графиков с различными темами и цветами, помогая сде-
лать графику более привлекательной.
4. Matplotlib (import matplotlib.pyplot as pit):
• Основные функции визуализации. Matplotlib является основным инс-
трументом для создания графиков в Python. С помощью pyplct, мы
можем создавать различные типы графиков (линейные, столбчатые,
рассеяния и т. д.) с детальной настройкой.
• Анимация и интерактивные графики. Matplotlib также поддерживает
создание анимаций и интерактивных графиков, что может быть необ-
ходимо при развитии более сложных проектов.
• Настройка графиков на низком уровне. Matplotlib предоставляет до-
ступ ко многим параметрам графиков, позволяя, например, изменять
шрифты, цвета, размеры и другие параметры, что делает библиотеку
мощным инструментом для настройки визуализаций.
I pip Install seaborn
R*quir«*«*t *lr««dy s*'lsfi*d: f«*bom in /ufr/loc»l/lib/python3.12/dist-p*ckei*» (0.13.2)
R*qulr«***t already satisfied] ливру I«1.24.©,>•!.20 in /usr/local/lib/pythonS.12/dlst•packages (fro* seaborn) (2.6.2)
Require***' already satisfied: pandas» 1.2 tn /usr/local/lib/py'h«xi3.12Zdi*'-packages (fro* teaborn) (2.2.2)
Require***' already satisfied: Matplotllbl«3.6.1,>«3.4 in /usr/local/lib/python3.12/dist-packag*s (fro* seaborn; (3.10.в)
Require***' already satisfied: contourpy>«l.9.1 in /usr/local/lib/pytbon).12/dis'-packages (fro* *atplotlib!«J.6.1,»3.4->seat>Qrn) (l.J.J)
Require***' already satisfied: cycl«r»6.19 in /usr/local/lib/pythonj.12/dis'•packages (fro* natplotlibI-3.6-1,»3.4->seaborn) (0-12.1)
Require***' already satisfied: fonttool*>«4.22.6 in /usr/loc*l/lib/py'bon3.12/dis'-p*ck*>ges (fro* «atplotlib! «5.6.1, »3.4->*евЬогл) (4.61.1)
Require***' already satisfied: kiwisolver» 1.3.1 in /usr/local/lib/ру'ЬолЗ.12/dis'-package* (fro* aatplotlib!*3.6.1,»3.4->seabor*) (1.4.9)
Require***' already satisfied] packaging»20.0 in /usr/local/lib/python3.12/dlst-packages (fro* *atpiotlibt«3.6.1,>«3.4->seabom) (2S.0)
Require***' already satisfied: pillo*»B in /usr/lccal/lib/py'ho*3.12/dist-package* (fro* aatplotlibI-3.6. l,»3.4->*«aborn) (11.3.0)
Require***' already satisfied. pyparsfng»2.3.1 in /usr/local/llb/python3.12/dist-packages (f'vu *atplotlibl«3.6.1,»3.4*>seaborn) (3.3.1)
Require***' already satisfied: pythondateutil>«2.7 in /use/local/lib/py'honl.l2/dlst packages (fro* *a'plotlibi«).6.i,>«3,4>s*abom) (2.9.0.post6)
Require***' already satisfied: py'£>-2020.1 in /usr/locai/llb/py'bon3.12/dis'° packages (fro* pandas>-l .2*>seabom) (2025.2)
Require***' already satisfied: trdata»2O22.7 in /vsr/loca 1/1 ib/python3.12/dist-packages (fr*a pandas»!.2->s*aborn) (2025.3)
Require***' already satisfied: six»l.$ in /usr/local/lib/python3.12/dist*pa<kages (fro* python-da'eirtil>-2.7->«atplotlib!-3-6.1.>-3.4->seaborn) (1.17.0)
Q |Ьфог t • seaborn - as seis
Irkm-c pandas as pd
s Cower' the 'data* dictionary to a Oa'afraae naaed 1 students_df‘ as required by sns.scatterplot
student*_df • pd.Oatafra*e(data)
pit Л igur*(f igsize-46, 5))
sns.s<a"*rplot(da'a-s'udents_df, x-'*a'h_scor*’, y-'reading_*core’, hue-’genderstyIt-’genders«160)
pit.tltle('Рассеяние баллоа no математик» и мтемма')
plt.xlabel (‘Балм по мате*апк«')
pit./label (‘Балм "О чч*м')
.ll-ttldO
plt.showO
Рассеяние баллов по математике и чтению
Рис. 9.26
Этап 3. Создание собственного набора данных и его визуализация.
1. Установка случайного зерна для воспроизводимости:
пр.random.seed(42)
Используем функцию пр.random.seed(42), чтобы установить начальное
значение (или «зерно») для генератора случайных чисел. Это позволяет обес-
печить воспроизводимость, так как при перезапуске кода с тем же начальным
значением, генератор будет выдавать тот же набор случайных чисел.
2. Определение количества студентов:
nurr._studer.ts = 1С0
Задаем переменную num students равной 100, что означает, что мы хотим
создать данные для 100 студентов.
3. Формирование словаря данных:
data = {
'student_id': range(l, num_students + 1),
'math score': np.random.randint (50, ICO, size=num_students),
' react! ng_ score': np.random.randint (50, 100, size=num_students),
'gender': np.random.choice(['male', 'female'], size=num_students),
'age': np.ranacm.randint (15, 22, size=num_students)
}
Создаем словарь data, в котором ключи представляют имена колонок,
а значения — это данные каждого студента:
• student id: — уникальный идентификатор для каждого студента, ко-
торый создается с помощью range (1, num students + 1);
* math score: — баллы ио математике для каждого студента, которые ге-
нерируются с помощью пр. random, randint (5С, 100, size=num_students).
Эта функция возвращает случайные целые числа от 50 до 99 (включи-
тельно);
• reading score: — баллы по чтению, созданные таким же образом, как
и баллы по математике;
• gender: — пол студента, который выбирается случайным образом из
списка [<male>, <female>] с помощью пр.random.choice (). Так мы по-
лучим равное количество мужчин и женщин;
• аде: — возраст студентов, генерируемый случайным образом с помо-
щью пр.random.randint(15, 22, size=num_stadents), что дает случай-
ные числа от 15 до 21 (включительно).
4. Создание DataFrame:
students_df = pd.DataFrame(data)
Создаем DataFrame students_df из словаря data. DataFrame — это основная
структура данных в Pandas, которая обеспечивает удобное представление
и манипуляцию табличными данными.
5. Просмотр первых пяти строк набора данных:
print (students df.headO)
Используя метод head(), выводим на экран первые пять строк нашего
DataFrame, чтобы быстро оценить, какие данные .мы создали и как они вы-
глядят.
6. Создание графика рассеяния (Scatter Plot):
pit.figure(figsize3(10, 5))
sns.scatterplot(data=students_df, x=' math_score', y='reading_score',
hue='qender', sty]e='gender', s=100)
pit.title('Рассеяние баллов по математике и чтению')
pit.xlabel('Баллы по математике')
plt.ylabel('Баллы по чтению')
plt.gridf)
pit.show()
Мы создаем новую фигуру с размером 10 на 5 дюймов для графика.
Используем sns.scatterplot() из Seaborn для рисования графика рассея-
ния, где:
• data=students_df: передает данные DataFrame;
♦ x='roath_sccre' : определяет, что по оси х будут расположены баллы по
математике;
• у= >reading_score >: определяет, что по оси у будут расположены баллы
по чтению;
• hue= >gender >: используется для окраски точек в зависимости от пола
студента (мужской или женский);
• style= >gender >: определяет стиль точек также в зависимости от пола;
• s=l00: задает размер точек.
Устанавливаем заголовок графика и подписи для осей, а затем отображаем
сетку для лучшей читабельности.
Функция pit.show() отображает трафик.
import seaborn •$ ins
ieport p«nd«s as pd
• Convert the 'data* dictionary to a DataFraee naaed '*tudents_df’ as required by sns.scatterplot
»tudents_df - pd.DataFraae(data)
plt.figure(figsize*(XOr S))
sns. scatterplot(dat»-sti*dent s_d?, x- 'eat h_score •, y-’readings core’, hue-'gender'4 style* ’gender’, s-XOO)
pit.title(‘Рассеяние баллов no математике и чтению')
pit,xlabel('баллы no математике‘)
plt.ylabel(’балл» no чтеммм')
plt.gridO
plt.show()
Рис. 9.27, 9.28
На этом этапе мы будем создавать линейный график (Line Plot), который
отображает средние баллы студентов по математике и чтению в зависимости
от их возраста. Давайте рассмотрим пошагово, что происходит в этом коде,
в виде алгоритма.
Этап 4. Создание линейного графика
1. Группировка данных по возрасту и расчет среднего:
mean scores = students_df.groupoy('age')[[’math_score', 'reading
score']].mean ().reset_index()
Используем метод groupby () из Pandas для группировки данных в DataFrame
students df по столбцу age (возраст).
Выбираем столбцы math_score и reading_score и вычисляем их средние
значения с помощью метода mean (). Получаем средние оценки по этим пред-
метам для каждого возраста.
Метод reset_index() используется для преобразования результата груп-
пировки в стандартный DataFrame, сбрасывая индекс и возвращая его в виде
колонок. В результате у нас появляется новый DataFrame raean_scores с тремя
колонками: age, math score, reading_score.
2. Создание фигуры для графика:
plt.figure(figsize-(lO, 5))
Создаем новую фигуру с заданным размером 10 на 5 дюймов. Это область,
на которой мы нарисуем график.
3. Построение линейного графика для среднего балла по математике:
sns.lineplot(data=mean scores, x='age', y='math score', iaoel='Средний
балл по математике', marker='o')
Используем функцию sns. lineplot () из Seaborn для построения линейно-
го графика:
• data=mean_scores — передаем DataFrame с рассчитанными средними
баллами;
• х= >аде > — по оси х располагаем возраст студентов;
• у= >math score > — по оси у располагаем средние баллы по математике;
• label= >Средний балл по математике > — задаем метку для графика, кото-
рая будет отображаться в легенде;
• marker= >о > — устанавливаем маркер (кружок) для точек на графике.
4. Построение линейного графика для среднего балла по чтению:
sns.lineplot(data=mean_scores, x='age', y='reading_score',
labels'Средний балл по чтению', marker='o')
Этот шаг аналогичен предыдущему, но теперь мы строим график для
среднего балла по чтению. Снова передаем данные mean_scores, но теперь
y='reading_score'.
5. Добавление заголовка и меток осей:
pit.title('Средние баллы по математике и чтению по возрасту')
pit.xlatel('Возраст')
pit.ylabel('Средние баллы')
Используем plt.titleO для установки заголовка графика, a plt.xlabel()
и plt.ylabel () — для установки меток на осях х и у соответственно.
6. Добавление легенды:
pit.legend()
Вызываем pit. legend (), чтобы отобразить легенду на графике. Она помо-
гает различать линии на графике, соответствующие средним баллам по мате-
матике и чтению.
7. Добавление сетки для удобства восприятия:
plt.grid()
Вызываем pit.grid() для добавления сетки на график, что делает его бо-
лее читабельным и помогает воспринимать данные.
8. Отображение графика:
pit.show()
Используем pit. show (), чтобы отобразить график на экране.
На этом этапе мы создали линейный график, который показывает, как
средние баллы по математике и чтению изменяются в зависимости от воз-
раста студентов Этот график позволяет легко визуализировать и сравнивать
производительность студентов по двум предметам с учетом их возраста.
Теперь создадим гистограмму, которая представляет распределение бал-
лов студентов по математике. Давайте рассмотрим шаги, участвующие в этом
процессе, в виде алгоритма.
Этап 5: Создание гистограммы
1. Создание фигуры для графика:
plt.figure(figsize=(10, 5))
Создаем новую фигуру для графика с заданным размером 10 на 5 дюймов.
Это область, на которой мы нарисуем гистограмму.
2. Построение гистограммы:
sns.histplot(data=students_df, x='math_score', bins=10, kde=True)
Используем функцию sns.histplot() из Seaborn для построения гистог-
раммы:
* data=students_df — передаем DataFrame students_df, который содер-
жит данные о студентах;
• x='math score' — по оси х располагаем баллы по математике, которые
хотим визуализировать;
* bins=10 — указываем количество корзин (или интервалов), на которые
будут разбиты данные. В данном случае мы хотим 10 корзин для рас-
пределения;
• kae=True — включаем отображение функции ядерной плотности (KDE),
которая накладывается на гистограмму и позволяет зрительно оценить
распределение данных, сглаживая его и показывая более плавную кри-
вую распределения вероятностей.
Пояснение новых понятий на примере.
Представьте, что вы — куратор образовательного проекта и вам нужно
проанализировагь результаты тестирования 200 участников. Данные уже соб-
раны, но «голые» цифры не дают картины. На помощь приходит Seaborn —
библиотека, превращающая статистику в наглядные истории.
1. Seaborn (sns): художник данных
Суть. Seaborn — это «дизайнерский слой» над Matplotlib. Она берет на се-
бя рутину: подбор цветов, отступов, шрифтов. Результат — графики, которые
не стыдно показать на презентации.
Почему sns? Короткое имя — не прихоть, а традиция. Так же, как pd для
Pandas или пр для NumPy. Это экономит время и делает код чище.
Реальный кейс. В нашем проекте Seaborn помог выявить:
• группу участников, застрявших на базовом уровне;
• неожиданный скачок результатов в возрастной категории 35-40 лет.
2. sns histplot (): гистограмма с характером
Что делает. Строит столбчатый график, где высота столбца = количество
наблюдений в диапазоне. Это как «фотоотчет» о распределении данных.
Неочевидный нюанс. Гистограмма — не просто счетчик. Она отвечает на
вопросы:
• Есть ли выбросы (участники с экстремально высокими/низкими ре-
зультатами)?
* Симметрично ли распределение или скошено в сторону лучших/худ-
ших показателей?
Пример из проекта. Построив гистограмму баллов по логике, мы замети-
ли «провал» в зоне 60-70 баллов. Это подтолкнуло к пересмотру сложности
промежуточных заданий.
3. data=results_df: источник истины
Что это. Ссылка на DataFrame — таблицу, где:
• строки = участники теста;
♦ столбцы = их параметры (возраст, баллы, время прохождения).
Лайфхак. Перед визуализацией всегда проверяйте:
python
print(results_df.shape) * Сколько строк и столбцов
print(results_df.columns) # Названия колонок
Это спасает от ошибки «график пустой», когда вы случайно указали не то
имя столбца.
Из практики. В наших данных был столбец time min (время в минутах).
Поначалу мы построили гистограмму по нему, но график выглядел хаотично.
Причина: несколько участников тратили на тест в 10 раз больше времени.
Решение — отфильтровать аномалии:
python
results_df = results_df[results_df['timejnin'] < 120]
4. x='logic_score’: ось с подсказкой
Смысл. Указывает, какой показатель визуализировать. В нашем случае —
баллы за логические задачи.
Тонкость. Имя столбца должно точно совпадать с тем, что в DataFrame.
Python не поймет, если вы напишете <Logic_Score> вместо <logic_score>.
Креативный прием. Мы добавили к оси X подпись с контекстом:
sns.histplot(daca=results df, х='logic sccre')
pit.xlabel('Баллы за логические задачи (макс. ICO)')
Так зритель сразу понимает масштаб.
5. bins=12: искусство дробления
Зачем нужно. Разбивает диапазон значений на интервалы. Например, при
bins=12 и максимальных 100 баллах каждый интервал будет ~8,3 балла.
Эксперимент. Мы попробовали разные значения:
• bins=5 — график слишком грубый, скрывает детали;
• bins=20 — появляются «шумовые» столбцы;
• bins=12 — золотой компромисс: видно и общие тренды, и локальные
пики.
Совет. Для данных с естественным делением (например, оценки от 1 до
10) ставьте bins равным этому диапазону.
6. kde=True: магия сглаживания
Что дает. Добавляет плавную кривую, которая «считывает» форму рас-
пределения. Это как фильтр для фото: убирает шум, оставляет суть.
Когда критично. В нашем проекте KDE выявил:
• два пика в распределении (группы «сильных» и «средних» участни-
ков);
• асимметрию вправо (больше людей с результатами выше среднего).
Фишка. Комбинируйте kde=True с цветовой заливкой:
python
sns.histplot(data=results_df, x='logic score', bins=12, kde=True,
color='skyblue')
Так график становится и информативным, и эстетичным.
Итоговый код с комментариями
import seaborn as sns
import matplotlib.pyplot as pit
# Строим гистограмму c KDE
sns.histplot(
data=results_df,
x='logic_score',
bins=12,
kde=True,
color='skyblue',
alpha=0.7
If Нади данные
f Что визуализируем
# Количество интервалов
# Добавляем сглаженную кривую
if Цвет столбцов
fr Прозрачность для эстетики
# Подписи и заголовок
pit.xlabel('Баллы за логические задачи (макс. 100)')
plt.ylabel('Количество участников')
pit.title('Распределение результатов тестирования')
pit.show()
Что мы получили:
* Наглядную картину успеваемости.
• Доказательства для корректировки программы.
• График, который можно вставить в отчет без дополнительных правок.
3. Добавление заголовка графика:
pit.title('Гистограмма баллов по математике')
Используем функцию pit.title () для установки заголовка графика, что-
бы дать представление о том, что именно на нем отображается.
4. Установка меток для осей:
pit.xlabel('Баллы по математике')
pit.ylabel('Частота')
Задаем метку для оси х с помощью pit .xlabel (), указывая, что здесь пред-
ставлены баллы по математике.
Устанавливаем метку для оси у с помощью plt.ylabel (), обозначая, что
она от ображает частоту (количество студентов в каждом интервале).
5. Добавление сетки:
pit.grid ()
Добавляем сетку на график с помощью plt.grido. Это улучшает воспри-
ятие графика и помогает лучше видеть, где уточнены значения.
6. Отображение графика;
plt.showO
Наконец, с помощью pit. show () выводим график на экран, чтобы увидеть
результат.
На этом этапе мы создали гисто! рамму, которая визуализирует распреде-
ление баллов студентов по математике. Гистограмма позволяет увидеть, как
часто определенные баллы встречаются среди студентов, и помогает выявить
тенденции, например каких студентов больше — с высокими баллами или
низкими. Включение функции ядерной плотности (KDE) позволяет более
точно понять распределение данных, добавляя плавную линию на гистограм-
му, что делает график более информативным.
А • Строми гжтогр*>*«у е KDC
*П*
Рис. 9.30
На этом этапе мы создадим бар-график, который визуализирует средние
баллы студентов но математике в зависимости от их пола. Давайте рассмот-
рим, что происходит в этом коде, в виде алгоритма.
Этап 6: Создание бар-графика
1. Создание фигуры для графика:
pit.figure(figsize=(10, 5))
Создаем новую фигуру для графика с заданным размером 10 на 5 дюймов.
Это обеспечит достаточное пространство для отображения бар-графика.
2. Построение бар-графика:
sns.barplot (daca=students df, x='ger.der', y='math_score', estimator=np.
mean, palette='coolwarm')
Используем функцию sns.barplot() из Seaborn для создания бар-графика.
data=students_df — передаем DataFrame students_df, который содержит
данные о студентах.
х='gender' — по оси х располагаем пол студентов, что позволяет визуаль-
но разделить данные по категориям (мужчины и женщины).
у= >math_score > — по оси у располагаем средние баллы по математике.
estimator=np.mean — указываем, что нужно использовать среднее значение
(mean) для вычисления высоты каждой колонки. Таким образом, бар-график
будет отображать средний балл по математике для каждой категории пола.
palette=' coolwarm' — задаем цветовую палитру для графика. В данном
случае мы используем палитру < coolwarm >, которая создает приятный визу-
альный контраст.
3. Добавление заголовка г рафика:
pit.title('Средние баллы по математике в зависимости от пола')
Используем функцию pit.titled для установки заголовка графика, что-
бы информировать зрителей о том, что представлено на графике.
4. Установка меток для осей:
plt.xlabel('Пол')
plt.ylabel('Средний балл по математике')
Задаем метку для оси х с помощью pit. xlabel (), указывая, что на этой оси
представлено разделение по полу.
Устанавливаем метку для оси у с помощью plt.ylabel (), обозначая, что
она отображает средний балл по математике.
5. Добавление сетки:
plt.gridO
Добавляем сетку на график, что улучшает восприятие и помогает анали-
зировать значения.
6. Отображение графика:
pit.show ()
Выводим график на экран, чтобы визуализировать представленные данные.
На этом этапе мы создали бар-график, который показывает средние бал-
лы студентов по математике в зависимости от их пола. Такой график позво-
ляет быстро сравнить результаты между мужчинами и женщинами, выявляя,
у какой группы студентов средние баллы выше. Бар-графики — эффектив-
ный способ визуализации категориальных данных, который помогает сде-
лать выводы на основе представленных данных.
0 14. (ter
plt.figMr«(Hg*ix«-i >e, »»
sni.ten>lot(dat4>stw4eets_4f, , уыИ^иогв , tstlwtor-ap.wMi, palette-' cool мага')
'Срадои* no матиитк» в авансmocта от пола*)
plt.>14ft«l('nui')
plt.yiateK*Средни* teM по мвтонатме*)
pH.gr W()
plt.>te»O
"" /tte/lpythM-lApUt-»M82M4.pyl)!
Patting 'palatta' witbeat «talgaing ’bu»’ It dapr«cat«d and will ba гавотаd In v#.14.g. Mtign tM variable to 'but' and tat ' l*g*M»faltt <or tha »aao effect.
tnt.berplot(data-Hvdeertt tff, x*'gender’, у'eath^Kora', «»tlootor-лр.neon, peltUe- coolwre')
Средние баллы no математике а зависимости от пола
female
mtoe
Лоя
Рис. 9.31
Этап 7. Создание коробчатой диаграммы
На этом этапе мы создадим коробчатую диаграмму (Box Plot), которая ви-
зуализирует распределение баллов студентов по чтению в зависимости от их
пола. Давайте рассмотрим шаги в этом процессе в виде алгоритма.
1. Создание фигуры для графика:
pit.figure (fiasize-(Ю, 5))
Создаем новую фигуру для графика с заданным размером 10 на 5 дюймов.
Это обеспечит достаточно пространства для отображения коробчатой диа-
граммы.
2. Построение коробчатой диаграммы:
sns.boxplot(data=students_df, х='gender', у='read:ng_score',
palette='Set2')
Используем функцию sns.boxplot () из Seaborn для создания коробчатой
диаграммы.
data= students_df — передаем DataFrame students df, который содержит
данные о студентах.
х='gender' — по оси х располагаем пол студентов, что позволяет визуаль-
но разделить данные на категории (мужчины и женщины).
у= >reading_score > — по оси у располагаем баллы по чтению. Это позволя
ет увидеть, как они распределяются для каждого пола.
palette= >Set2 > — задаем цветовую палитру для графика, в данном случае
используется палитра <Set2>, которая создает приятные цвета для визуали-
зации.
3. Добавление заголовка графика:
plt.title('Коробчатая диаграмма баллов по чтению в зависимости от пола')
Используем функцию pit.title () для установки заголовка графика, что-
бы дать представление о том, что именно представлено на графике.
4. Установка меток для осей:
plt.xlabel('Пол')
pit.ylabel('Валлы по чтению')
Задаем метку для оси х с помощью pit. xlabel (), указывая, что на этой оси
представлено разделение по полу.
Устанавливаем метку для оси у с помощью plt.ylabei (), обозначая, что
она отображает баллы по чтению.
5. Добавление сетки:
plt.gridO
Добавляем сетку на график. Это улучшает восприятие графика и помогает
лучше видеть, где находятся значения на оси у.
6. Отображение графика:
plt.showO
Выводим график на экран, чтобы увидеть результат.
На этом этапе мы создали коробчатую диаграмму, которая визуализи-
рует распределение баллов студентов по чтению в зависимости от их пола.
Коробчатая диаграмма позволяет увидеть медиану, квартили и возможные
выбросы в данных. Это удобно для сравнения распределения баллов между
группами (в данном случае мужчинами и женщинами) и позволяет выявить
любые значимые различия между ними.
Q К«*о4чате« диаграмм Оок Plot)
plt-ilp-reff JeiUe*[to» »))
, ж-‘fender', у-’readin<_score', palette-’Set1)
pit. title('Ка*о4чата<е деагрмм Ьал-ое па -те-a* мксохг» от гхм»’>
plt.xlabel ‘Поп')
pit .у1аЬе1('Ьои*> *О чте—•')
Pit .Г«()
plt.sho«()
/tRS/lpytKoci'laput 4dl5dS4457.pyiSi FutureMarnlAf:
Passing 'palette' without assigning 'hue' Is deprecated and will be moved tn vd.ia.d. assign the variable to 'hue' and set 'legend^alse' for the sane effect.
MM .bosplot(deta*stwdenti_df, я-'gender', у ‘ rvadlnj score* . palette»"SetI")
Коробчатая диаграмма баллов no чтению в зависимости от пола
к» - ” —""
ПОЛ
Этап 8. Создание скутерной диаграммы
На этом этапе мы создадим скутерную диаграмму (Violin Plot), которая
визуализирует распределение баллов студентов по математике в зависимос-
ти от их пола. Давайте подробно рассмотрим шаги в этом процессе в виде
алгоритма.
1. Создание фигуры для графика:
pit.figure(figsize= (10, 5))
Создаем новую фигуру для графика с заданным размером 10 на 5 дюймов.
Это обеспечит достаточно пространства для отображения скутерной диа-
граммы.
2. Построение скутерной диаграммы:
sns.violinplot(data=stuaents_df, x='gender', y='math_score',
split=True)
Используем функцию sr.s.violir.plot() из Seaborn для создания скутер-
ной диаграммы.
data=students df — передаем DataFrame students df, который содержит
данные о студентах.
х=' gender' — по оси х располагаем пол студентов, что позволяет визуаль-
но разделить данные на категории (мужчины и женщины).
у= >math_score > — по оси у располагаем баллы по математике. Так мы уви-
дим, как баллы по математике распределяются для каждой категории пола.
split=True — указываем, что хотим разделить скутерную диаграмму на
две части для каждой категории, чтобы визуально сравнить распределение
между мужчинами и женщинами в одной диаграмме.
3. Добавление заголовка графика:
pit.title('Скутерная диаграмма баллов по математике в зависимости от
пела')
Используем функцию pit.title () для установки заголовка графика, что-
бы информировать зрителей о том, что представлено на графике.
4. Установка меток для осей:
plt.xlabel('Пол')
plt.ylabel('Баллы по математике')
Задаем метку для оси х, указывая, что на ней представлено разделение по
полу.
Устанавливаем метку для оси у, обозначая, что она отображает баллы по
математике.
5. Добавление сетки;
pit. grid () — добавляем сетку на график, что улучшает восприятие и дела-
ет значения более четкими.
6. Отображение графика:
pit.show() — выводим график на экран, чтобы увидеть результат.
На этом этапе мы создали скутерную диаграмму (Violin Plot), которая ви-
зуализирует распределение баллов студентов по математике в зависимости
от их пола. Скутерная диаграмма позволяет увидеть не только медиану, но
и более детальную информацию о распределении данных, включая форму
распределения и плотности. Это полезно для выявления особенностей в дан-
ных, таких как наличие нескольких модов, которые могут указывать на раз-
ные группы учащихся с различными уровнями подготовки.
Qt • 6. Violin Plot (Скутерная диаграмм)
pit.figure(figsize-(10, S))
sns .violinplot (data-s tiedent s_df, x»"gender \ y«‘»ath_score', split-True)
pit.title("Скутерная днагранил баллов по натематике в зависимости от пола')
pit.xlabel(’Пол')
pit.уlabel(’Баллы по математике4)
plt.gridO
plt.show()
i
?
g
Е
Я
Скутерная диаграмма баллов по математике в зависимости от пола
female
maie
Пол
Рис. 9.33
Этап 9. Создание регрессионного графика
На этом этапе мы создадим регрессионный график, который отображает
связь между баллами студентов по математике и чтению. Давайте подробно
рассмотрим шаги в этом процессе в виде алгоритма.
1. Создание фигуры для графика:
pit.figure(figsize= (10, 5))
Создаем новую фигуру для графика с заданным размером ) 0 на 5 дюймов.
Это обеспечит достаточно пространства для отображения регрессионного
графика.
2. Построение регрессионного графика:
sns.regplot (data=stude.nts_df, x='math_score', y='reading_score',
scatterjcws={'alpha': C.5}, line_kws=("color": "red"})
Используем функцию sns.regpljt () из Seaborn для создания регрессион-
ного графика.
data=students_df — передаем DataFrame students_df, который содержит
данные о студентах.
x='math_score' — по оси х располагаем баллы по математике.
у= >reading_sccre > — ио оси у располагаем баллы по чтению.
scatter_kws={<alpha>: 0.5} — задаем параметры для точек рассеяния
(scatter), в данном случае указываем уровень прозрачности (alpha=C.5), что
позволяет сгладить наложение точек и делать график более читабельным.
line_kws= {"color": "red"} — задаем параметры для линий регрессии, из-
меняя цвет линии на красный.
3. Добавление заголовка графика:
pit.title('Регрессионный график: чтение по математике')
Используем функцию pit.title () для установки заголовка графика, что-
бы дать представление о том, что именно отображается на графике.
4. Установка меток для осей:
pit.xlabel('Баллы по математике')
plt.ylabel('Баллы по чтению')
Задаем метку для оси х с помощью pit. xlabel (), указывая, что на этой оси
представлены баллы по математике.
Устанавливаем метку для оси у с помощью plt.ylabel(), обозначая, что
она отображает баллы по чтению.
5. Добавление сетки:
plt.gridO
Добавляем сетку на график, что улучшает его восприятие и помогает ана-
лизировать значения.
6. Отображение графика:
pit.show()
Выводим график на экран, чтобы увидеть результат.
На этом этапе мы создали регрессионный график, который визуализирует
зависимость между баллами студентов по математике и чтению. Регрессион-
ный график не только показывает данные в виде точек, но и предоставляет
линию регрессии, которая помогает оценить и визуализировать тренд между
переменными. Этот график позволяет нам увидеть, как изменение баллов по
математике может быть связано с изменением баллов по чтению, что полезно
для анализа взаимосвязи между академическими успехами студентов.
О > 7. р«гр«ссмоннмй график (Regression Plot,
pit-figure(figsize-(10, $))
sns.regplot(detа-students_df, x«*eath_score*t у‘reading score *. sea tter_kwn»{'alpha' : 0.5}* line_kws«{“color": "red"})
plt.title('PerpecсмойwS график: чтение no математике*)
pit.xlabel('Баллы no математике’)
pit.уlabel('Баллы no чтение’)
plt.grido
plt.showO
Баллы no математике
I pip Install nuapy
Рис. 9.34
Выводы
В главе рассмотрены ключевые подходы и инструменты для визуализации
данных и создания интерактивных элементов в среде Google Colab. Основные
выводы:
1. Многообразие инструментов для интерактивности
Для создания интерактивных элементов (кнопок, слайдеров, тексто-
вых полей) в Jupyter Notebook/Colab подходит библиотека ipywidgets.
Она позволяет оперативно встраивать управляемые компоненты
прямо в рабочую среду, упрощая прототипирование пользователь-
ских интерфейсов.
Пример: с помощью widgets .Text и observe () можно отслеживать из-
менения ввода и реагировать на них в реальном времени.
2. Matplotlib — фундамент визуализации
Библиотека Matplotlib предоставляет универсальный набор инстру-
ментов для построения графиков любого типа: линейных, точечных,
гистограмм, бар-графиков, круговых диаграмм, тепловых карт и др.
Ключевые возможности:
• настройка стилей линий (linestyle, color, linewidth);
• работа с логарифмическими шкалами (xscale, yscale);
• создание подграфиков (subplots);
• добавление аннотаций и текста (annotate, text);
• сохранение графиков в файлы с заданным разрешением
(savefig).
Matplotlib интегрируется с NumPy и Pandas, что делает ее удобной для
анализа и представления данных.
3. Seaborn — продвинутая визуализация
Seaborn дополняет Matplotlib, предлагая высокоуровневые интерфей-
сы для создания эстетически привлекательных и информативных
графиков.
Преимущества:
• упрощенное построение сложных диаграмм (например,
scatterplot, lineplot, histplot);
• встроенная поддержка статистических методов (довери-
тельные интервалы, KDE-линии);
• готовые цветовые палитры и темы оформления,
• удобная работа с категориальными данными (например,
разделение по группам через hue и style).
Примеры использования:
• коробчатые диаграммы (boxplot) для анализа распределе-
ния данных;
• скутерные диаграммы (violinplot) для визуализации плот-
ности распределения;
• регрессионные графики (regplot) для выявления взаимосвя-
зей между переменными.
4. Интеграция с данными
Библиотеки Pandas и NumPy играют ключевую роль в подготовке
данных для визуализации;
• Pandas обеспечивает удобную работу с таблицами
(DataFrame), фильтрацию и агрегацию;
• NumPy позволяет эффективно обрабатывать массивы дан-
ных, генерировать случайные значения и выполнять мате-
матические операции.
Пример: создание синтетического набора данных о студентах с пос-
ледующим анализом средних баллов по возрасту и полу.
5. Праю ические сценарии в Google Colab
Все рассмотренные инструменты (ipywidgets, Matplotlib, Seaborn)
полностью совместимы с Google Colab, что позволяет:
• быстро прототипировать визуализации без локальной ус-
тановки НО;
• комбинировать интерактивные элементы с аналитически-
ми графиками;
• сохранять результаты в файлы (например, PNG) для даль-
нейшего использования.
Важный аспект: Colab поддерживает выполнение кода в ячейках, что
упрощает пошаговое тестирование и демонстрацию возможностей
библиотек.
6. Гибкость настройки графиков
Пользователи могут:
• изменять размеры фигур (figsize);
• добавлять сетки (grid), легенды (legend), подписи осей;
• настраивать прозрачность (alpha), маркеры (marker), цвета
(palette);
• комбинировать несколько графиков на одном полотне (на-
пример, линии и заполненные области через f ill_between).
Итоговый вывод
Глава демонстрирует, что Google Colab в сочетании с библиотеками Python
(ipywidgets, Matplotlib, Seaborn, Pandas, NumPy) предоставляет мощную эко-
систему для:
• интерактивной разработки пользовательских интерфейсов;
• комплексного анализа данных через визуализацию;
• создания профессиональных отчетов и презентаций с графиками.
Эти инструменты особенно ценны для исследователей, аналитиков и раз-
работчиков, работающих в облачной среде, так как позволяют сосредоточить-
ся на решении задач, не отвлекаясь на настройку локального окружения.
Глава 10
Применение Python
в научных вычислениях,
анализе данных
и машинном обучении
Научные вычисления и анализ данных
В основе современных научных исследований и инженерных разработок
лежит эффективное управление и обработка данных. Python, благодаря на-
личию мощных библиотек, таких как NumPy и Pandas, предоставляет ис-
следователям и аналитикам инструментарий для решения задач, связанных
с численными вычислениями, статистическим анализом и визуализацией
данных.
Библиотека NumPy: основы работы
с многомерными массивами
NumPy 196] — краеугольный камень для научных вычислений в Python, пре-
доставляя реализацию высокопроизводительных многомерных массивов
и сопутствующих математических функций. Это позволяет значительно ус-
корить выполнение вычислительно интенсивных операций, таких как линей-
ная алгебра, статистический анализ и обработка сигналов.
Основные возможности NumPy
NumPy-массивы обеспечивают компактное и эффективное хранение дан-
ных, а также предоставляют богатый набор методов для их обработки.
Этап 1. Установка и импорт библиотеки NumPy
На этом этапе мы установим библиотеку NumPy и импортируем ее в на-
шу рабочую среду. Рассмотрим шаги, которые необходимо выполнить в этом
процессе.
1. Проверка наличия Num Ру.
Прежде чем устанавливать библиотеку, стоит убедиться, что NumPy не ус-
тановлен. В некоторых средах, таких как Google Colab, она предустановлена.
2. Установка NumPy (если она не установлена):
Ipip install numpy
Используем команду pip install для загрузки и установки библиотеки
NumPy. Знак ! перед командой позволяет выполнять системные команды
в среде Jupyter Notebook или Google Colab.
Эта команда подключается к репозиториям Python Package Index (PyPI)
и загружает последнюю стабильную версию библиотеки NumPy.
3. Импортирование библиотеки;
import numpy as np
После установки импортируем библиотеку NumPy, давая ей псевдоним пр.
Это сокращение позволяет писать код более компактно, облегчая обращение
к функциям и методам NumPy.
Таким образом, мы теперь можем использовать функции и классы библи-
отеки NumPy, обращаясь к ним через эту аббревиатуру (например, np. ar ray,
пр.zeros и т. д.).
Па этом этапе мы установили библиотеку NumPy (если она еще не была
установлена) и импортировали ее в рабочий код. Это позволяет нам исполь-
зовать все возможности и функции, которые предоставляет NumPy, для вы-
полнения различных математических и статистических операций с массива-
ми и матрицами в Python.
! pip fnitall пиару
— Kaqulrpaaat already uthfMi «напру U> /(rtr/local/llb/pytho«i3.i2/dltt-pocit4(«» (2.4.2)
Up art тару np
Bl. Соядание массивов
• о»«омер**й м* *сс^ (вектор)
vector np,array((5. 1», 15 j »])
print ("Одномертаа массив:vector)
• “e«f (aaaryaua)
wtrlx - r.p,.ref([[l. J, J), [4. s 6). P, 8. ♦]])
prlet<’Двунер«мй массив! \n", eatrbt)
• 2. Проверка «ком
print ("ворам aaacewe:", oetrix. а форам песета
print ('Количество «iMtpemt*:", eatrix.ndla) • «шмчестпо ивмарсмжЛ
рг1м(*<Ли»г цичпкгю «леваемтоо;", aetrix.tlre) а «оочцтю xmwmto*
pclrrt("T«rt AOinant;*. rtrlx.dtype) • тип данашх unvrto» маеема
• 3. Соаааннт масс»«оа с гюмомао спхчиальимх фуипааФ
Idantityaatrlx - нр.ауа(Э) В ijf eiaa матрица 3x3
print('Единичная матрацаi\n*, ldentlty_natrlx)
randoa_array - np.randoa.randoa(,3, 2)) а мае ем едучамамя масел размерен 3x2
print ('Нас с на слунаЬмм чисел!Чл", randoa.array)
а *. Доступ <с элементам и сремм
printСПеромй »еме*т naccaaai’, rector) а доступ первому жлемемту
print Отавит « 1 па Ji", vectorTnjl) а сое»
Этан 2. Создание массивов с использованием NumPy
На этом этапе мы создадим одномерные и двумерные массивы с помощью
библиотеки Num Ру.
1. Создание одномерного массива (вектор):
vector = пр.array([5, 10, 15, 20])
Используем функцию пр.array() для создания одномерного массива (век-
тора) с элементами 5, 10, 15 и 20. Он представляет собой последовательность
чисел и будет хранить данные в единой структуре.
2. Вывод одномерного массива:
print("Одномерный массив:", vector)
Используем функцию print () для вывода содержимого одномерного мас-
сива. Мы делаем это, чтобы убедиться, что массив был создан успешно и со-
держит ожидаемые значения.
3. Создание двумерного массива (матрица):
matrix = пр.array([[1, 2, 31, [4, 5, б], [7, 8, 9]])
Создаем двумерный массив (или матрицу) с использованием функции
пр.array (). Он состоит из трех строк, каждая из которых содержит три эле-
мента (числа от 1 до 9). Это позволит нам работать с более сложными струк-
турами данных, такими как таблицы и матрицы, что полезно для научных
вычислений и анализа данных.
4. Вывод двумерного массива:
print("Двумерный массив:\n", matrix)
Используем функцию print () с параметром \п, чтобы напечатать заголо-
вок и сам двумерный массив. Символ \п создает перенос строки, чтобы вы-
вести данные в более удобочитаемом формате.
Requirement already satisfied: numpy in /usr/local/lib/pyttH>n3.12/dist packages (2.0.2)
import numpy as np
--------------------------------------------------- Ф У © :
Q 91. Создание массивов
9 Одномерный массив (вектор)
vector - np.array((5, 10, 15, 20J)
ргint("Одномерный массив:*', vector)
# Двумерный массив (матрица)
matrix np.array(((l, 2, 3], [4, $, 6], [7, 8, 9]])
рг1п1("Двумерный массив:\п", matrix)
••• Одномерный массив: [ 5 10 15 20 J
Двумерный массив:
{(1 2 3]
(4 5 Б]
(7 8 9J]
в 2. Проверка свойств массива
print("Форма массива:**, matrix.shape) 9 форма массива
print('*KonM4ecTBO измерений:*', matrix.ndim) 9 количество измерений
На этом этане мы создали как одномерный, так и двумерный массивы
с использованием функций библиотеки NumPy. Эти массивы представляют
собой основные структуры данных, которые мы будем использовать в даль-
нейших расчетах и операциях. Убедившись в корректности создания масси-
вов, мы можем продолжать использовать их для выполнения различных ма-
тематических операций и анализа данных.
Этап 3. Проверка свойств массивов в NumPy
На этом этапе мы проверяем свойства созданного двумерного массива,
используя функции и атрибуты библиотеки NumPy. Это позволяет понимать
структуру наших данных и их характеристики.
1. Проверка формы массива:
print("Форма массива:", matrix.shape)
Используем атрибут .shape для получения формы двумерного масси-
ва. Этот атрибут возвращает кортеж, который указывает количество строк
и столбцов в массиве. В нашем примере, так как мы создали матрицу 3x3,
вывод будет (3, 3), что означает, что массив состоит из 3 строк и 3 столбцов.
2. Определение количества измерений:
print("Количестве измерений:", matrix.ndim)
Применяем атрибут .ndim для получения количества измерений (или ран-
га) массива. Это полезно для понимания структуры данных. Так как matrix
является двумерным массивом, вывод будет равен 2.
3. Общее количество элементов:
print("06mee количество элементов:", matrix.size)
Используем атрибут .size для определения общего количества элементов
в массиве. Этот атрибут возвращает количество всех элементов в массиве.
Для данной матрицы 3x3 общее количество элементов будет равно 9
4. Определение типа данных элементов:
print("Тип данных:", matrix.dtype)
Применяем атрибут . dtype для получения типа данных, которые хранятся
в массиве. Это полезно для понимания того, как данные будут обрабатывать-
ся в вычислениях. Если элементы массива имеют целочисленный тип (напри-
мер, int), вывод будет int64 (или int32, в зависимости от системы и версии
Python).
На этом этапе мы проверили важные свойства созданного нами двумерно-
го массива. Понимание формы, числа измерений, общего количества элемен-
тов и типа данных в массиве — важный шаг, который поможет в дальнейшей
работе с данными. Эта информация позволяет нам эффективно манипулиро-
вать нашими массивами, а также применять соответствующие математичес-
кие и статистические методы к данным.
14 S 6|
[/ 8 9]]
Ф #2. Проверка свойств массива |
print("Форма массива:", matrix.shape) 9 форма массива
print("Количество измерений:", Matrix.ndin) в количество измерений
print("O6ujee количество элементов:", matrix.size) 9 количество элементов
print("Twn данных:", matrix.dtype) 9 тип данных элементов массива
Форма массива: (3, 3)
Количество измерений: 2
Общее количество элементов: 9
Тип данных: int64
9 3. Создание массивов с помощью специальных функций
ldentity_matrix - пр.еуе(З) м единичная матрица 3x3
print("Единичная матрица:\n", identitymatrix)
random_array - np.random.random((3, 2)) « массив случайных чисел размером 3x2
print(“MaccHB случайных чисел;\n", random_array)
Я 4. Доступ к элементам и срезам
Рис 10.3
Этап 4. Создание массивов с помощью специальных функций NumPy
На этом этапе мы используем специальные функции библиотеки NumPy
для создания массивов с заранее определенными структурами. Создадим
единичную матрицу и массив случайных чисел.
1. Создание единичной матрицы:
identityjnatrix = np.eye(3) # единичная матрица 3x3
Используем функцию np.eye(3) для создания единичной матрицы разме-
ром 3x3. Она имеет единицы на главной диагонали и нули во всех остальных
позициях. Эта матрица часто используется в линейной алгебре и является
аналогом числа 1 при умножении матриц.
2. Вывод единичной матрицы:
print("Единичная матрица:\n", identityjnatrix)
С помощью функции print () выводим созданную единичную матрицу на
экран, чтобы убедиться, что она была сформирована правильно.
3. Создание массива случайных чисел:
randcm_array = np.random.random((3, 2)) к массив случайных чисел раз-
мером 3x2
Применяем функцию пр.random.random((3, 2)) для генерации массива
случайных чисел с размером 3x2. Получится массив, содержащий 3 строки
и 2 столбца, заполненный случайными числами в диапазоне от 0 до 1. Это
полезно для тестирования алгоритмов, работы с моделями машинного обу-
чения или при работе с выборками данных.
4. Вывод массива случайных чисел:
print("Массив случайных чисел:\п", random_array)
Используем функцию print () для отображения массива случайных чисел
на экране, что позволяет увидеть полученные значения и убедиться в коррек-
тности построения.
На этом этапе мы создали единичную матрицу и массив случайных чисел
с использованием специальных функций NumPy. Использование таких фун-
кций упрощает и ускоряет процесс создания массивов с заданной структу-
рой, что важно для подготовки данных для анализа и вычислений. Значения
сгенерированных случайных чисел могут быть использованы в различных
математических задачах, моделировании и алгоритмах.
Форма массива: (3, 3)
Количество измерений: 2
Обвее количество элементов: 9
Тип данных: int64
,---------------------------------------------------------------------------------------------------- Ф Ф V 0 :
ф И 3. Создание массивов с помощыо специальных функций [
identity_«atrix лр.еуе(З) л единична») матрица 3x3
print(“Единичная матрица:\п", identity_*atrix)
rando«_array np.rando*.randooi((3, 2)) 9 массив случайных чисел размером 3x2
print(“Maccne случайных чисел:\п“, randoearray)
••• Единичная матрица:
1(1. О- 0-J
[в. 1. ©.]
te. е. i.jj
Массив случайных чисел:
[[0.40697191 0.89148002]
[0.00292103 0.03976596]
[0.60407168 0.90738016])
• 4. Доступ к элементам и срезам
рг1п1(”Псрпый элемент массива:", vector) # доступ к первому элементу
print("Элементм г 1 по 3:". vertorfl:311 ft спеч
Рис. 10.4
Этап 5. Доступ к элементам и срезы массивов в NumPy
На этом этапе мы изучим, как получать доступ к отдельным элементам
массивов, а также как делать срезы для создания подмассивов. А также уви-
дим, как можно изменять значения в массиве.
1. Доступ к первому элементу массива.
print("Первый элемент массива:", vectorfO]) 4 доступ к первому элементу
Используем индексирование для получения доступа к первому элементу
массива vector. В Python индексация начинается с нуля, поэтому vector [0]
вернет первый элемент. С помощью функции print () выводим значение пер-
вого элемента, чтобы убедиться, что можем успешно получать доступ к эле-
ментам массива.
2. Срез элементов массива:
print("Элементы с 1 по 3:", vector[1:3]) | срез
Используем срез для извлечения подмассива. Запись vector (1:3] означает,
что мы извлекаем элементы с индексами 1 и 2 (то есть второй и третий эле-
менты). Работа со срезами позволяет удобно манипулировать частями масси-
ва, что особенно полезно при анализе данных.
3. Изменение значений в массиве:
vector[2] = 100 # изменение значения третьего элемента
Обновляем значение на третьей позиции (индекс 2) в массиве vector, при-
сваивая ему новое значение 100. Это позволяет изменять данные в массиве
без создания нового, что делает обработку данных более эффективной.
4. Вывод измененного массива:
print("Измененный массив:", vector)
После изменения значения повторно используем функцию print() для
отображения всего массива, чтобы убедиться, что изменения были успешно
применены.
На этом этапе мы изучили, как получать доступ к элементам массивов
в NumPy, создавать срезы для работы с подмассивами и изменять значения
существующих элементов. Эти навыки важны для манипулирования данны-
ми и подготовки их для дальнейших анализов и вычислений. Умение точно
управлять элементами массивов помогает более эффективно решать задачи
в области анализа данных и научных исследований.
[(1. е. о.]
[в. 1. е.]
[о. о. 1.ц
Массив случайных чисел:
[[0.40697191 Л.89148007]
[0.00292103 0.03976596]
[0.60402168 0.90738016]]
С Я 4. Доступ к элсмен1ам и среза*{
print("fiepeuh элемент массива:", vector) Я доступ к первому элементу
print ("Элементы с 1 по 3:", vector[l:3J) It срез
я Изменение значений в массиве
vector 100
print("Изменённый массив:”, vector)
••• Первый элемент массива: [ 5 10 15 20]
Элементы с 1 по 3: [10 15]
Изменённый массив: 100
Я 5. Арифметические операции
аггау_а = пр.аггау([3, 6, 9])
аггау_Ь = пр.аггау((1, 2, 3])
Я Сложение массивов
Этап 6. Арифметические операции с массивами в NumPy
На этом этапе мы будем выполнять основные арифметические операции,
такие как сложение, вычитание, умножение и деление. Эти операции позво-
ляют производить вычисления над массивами, что является одной из основ-
ных функций Num Ру.
1. Создание массивов для операций:
array_a = пр.array([3, 6, 9])
array b = пр.array((1, 2, 3j)
Создаем два одномерных массива: array а и array о. Первый массив со-
держит числа 3, 6 и 9, а второй — 1, 2 и 3. Эти массивы будут использоваться
в арифметических операциях.
2. Сложение массивов:
resultsum = array_a + array_b
Выполняем операцию сложения на двух массивах аггау а и array b. Это
происходит поэлементно: каждый элемент первого массива складывается
с соответствующим элементом второго. Результат сохраняем в переменной
result_sum.
3. Вывод результата сложения:
print("Результат сложения:", result_sum)
Используем print () для отображения результата сложения. Ожидаемый
вывод — массив, содержащий сумму соответствующих элементов обоих мас-
сивов.
4. Вычитание массивов:
result subtract = array а - array b
Проводим вычитание элементов второго массива из первого. Операция
аналогична сложению — выполняется поэлементно. Полученный результат
сохраняем в переменной result subtract.
5. Вывод результата вычитания:
print("Результат вычитания:", result subtract)
Снова используем print () для вывода результата вычитания, что позволя-
ет увидеть разницу между соответствующими элементами массивов.
6. Умножение массивов:
result multiply = array а * array b
11роизводим умножение соответствующих элементов обоих массивов. Ре-
зультат операции сохраняем в переменной resultjnultiply. Каждое значение
первого массива будет умножено на соответствующее значение второго.
7. Вывод результата умножения:
print("Результат умножения:", result multiply)
Выводим результат произведения массивов с помощью функции print ().
8. Деление массивов:
result_divide = array_a / array_b
Выполняем операцию деления на соответствующих элементах массивов.
Значения первого массива делятся на значения второго. Результат сохраняем
в переменной result divide.
9. Вывод результата деления:
print("Результат деления:", result_divide)
Последним шагом отображаем результат деления массивов, чтобы иметь
возможность видеть, как изменяются значения.
Мы выполнили основные арифметические операции (сложение, вычита-
ние, умножение и деление) с массивами NuniPy. Такие операции позволяют
производить пользователям сложные математические вычисления и анализ
данных непосредственно с массивами. Это один из ключевых аспектов рабо-
ты с библиотекой NumPy, который позволяет разработчикам легко обраба-
тывать и анализировать большие объемы данных.
------------------------------------------------------------------------------------------------------- Ф Ф 0 2
й 5. Арифметические операции
arrays » np.аггау([3, б, 9])
array_b - np.array([1, 2, 3])
» Сложение массивов
result_sue аггау_а ♦ array_b
рг1п|[("Результат сложения:", resultr suwi)|
в Вычитание массивов
result_subtract • arrays - array_b
print("Результат вычитания:", result_subtract)
tt Умножение массивов
result_«ultiply ® array_a * array_b
рг!п1("Результат умножения:", result_«ultiply)
й Деление массивов
result_divide аггау_а / array_b
print("Результат деления:", result_divide)
••• Результат сложения: [4 8 12]
Результат вычитания: [246]
Результат умножения: ( 3 12 27]
Результат деления: [3. 3. 3.]
в 6. Статистические функции
Рис. 10.6
Этап 7. Статистические функции для массивов в NumPy
На этом этапе мы будем применять статистические функции NumPy, что-
бы получить различную информацию о массиве. Мы научимся вычислять
сумму, среднее значение, максимальное и минимальное значения элементов
массива. Это позволит анализировать данные и делать выводы.
1. Вычисление суммы элементов массива:
рг!пс("Сумма элементов: ", np.sum(array_a)) # сумма всех элементов
Используем функцию np.sum() для вычисления суммы всех элементов
массива аггау_а. Она сканирует массив и возвращает общее значение, кото-
рое затем выводится на экран с помощью print ().
2. Вычисление среднего значения:
print("Среднее значение: ", np.mean(array а)) # среднее значение
Применяем функцию пр.mean() для вычисления среднего значения эле-
ментов массива аггау а. Она суммирует все элементы массива и делит на
их количество, чтобы получить усредненное значение. Результат выводится
с помощью print ().
3. Вычисление максимального значения:
print("Максимальное значение: ", np.max(array_a)) # максимальный элемент
Используем функцию np.maxO для нахождения максимального элемента
в массиве аггау_а. Функция проходит по всем элементам массива и возвра-
щает наибольшее значение. Результат также выводится на экран.
4. Вычисление минимального значения:
print("Минимальное значение: ", np.min(аггау_а)) # минимальный элемент
Применяем функцию np.min() для нахождения минимального элемен-
та в массиве аггауа. Она возвращает наименьшее значение, обнаруженное
в массиве, и выводит его на экран с помощью print ().
Мы ознакомились с использованием простых статистических функций
NumPy для анализа элементов массивов. Получили информацию о сумме,
среднем, максимальном и минимальном значениях, что позволяет прово-
дить базовый анализ данных. Эти статистические функции очень полезны
в исследовательской работе, где необходимы анализ и интерпретация боль-
ших наборов данных. С помощью NumPy подобные операции выполняются
быстро и эффективно, что значительно упрощает анализ численных данных
в Python.
8 Деление массивов
result_divide • аггауа / аггау_Ь
print("Результат деления:", result_divide)
Результат сложения: (4 8 12]
Результат вычитания: (246)
Результат умножения: ( 3 12 27]
Результат деления: (3. 3. 3.)
---------------------------------------------------------------------------------------------------- ф ф V ©
ф в 6 Статистические функции
print("Сумма элементов: ", пр.$им(аггау_а)) 0 сумма всех элементов
рг1пГ("Среднее значение: ", пр.меап(аггауа)) » среднее значение
рг1п1("Максимальное значение: ", пр.мах(аггау_а)) в максимальный элемент
print("Минимальное значение: ", np.ein(arraya)) 0 минимальный элеменл
••• Сумма элементов: 18
Среднее значение: 6.8
Максимальное значение: 9
Минимальное значение: 3
0 7. Изменение формы и транспонирование
reshaped_array np.re$hape(array_a, (3, 1)) 9 изменение формы на вертикальный вектор
print(“Изменённый массив (с двумя измерениями):\n", reshapedarray)
Этап 8. Изменение формы, транспонирование и матричные операции
в NumPy
На этом этапе мы изучим, как изменять форму массивов, транспониро-
вать матрицы и выполнять матричные операции, такие как умножение мат-
риц. Эти операции важны для работы с многомерными массивами и матри-
цами в линейной алгебре.
1. Изменение формы массива:
reshaped array = пр.reshape(array а, (3, 1)) # изменение формы на вер-
тикальный вектор
Используем функцию пр.reshape() для изменения формы одномерного
массива аггау а на двумерный массив (вертикальный вектор) с тремя стро-
ками и одним столбцом. Результат сохраняем в переменной reshaped_array,
чтобы мы могли видеть новый формат представления данных.
2. Вывод измененного массива:
print("Измененный массив (с двумя измерениями):\n", reshaped_array)
С помощью print () выводим измененный массив на экран, чтобы убе-
диться, что форма была изменена правильно.
3. Транспонирование двумерного массива:
transposed matrix = matrix.?
Применяем атрибут . Т к двумерному массиву matrix для его транспониро-
вания. Транспонирование меняет местами строки и столбцы массива. Резуль-
тат сохраняем в переменной transpcsedjnatrix.
4. Вывод транспонированной матрицы:
print("Транспонированная матрица:\п", transposedjnatrix)
Используем print () для отображения транспонированной матрицы, что
позволяем увидеть, как изменились ее с троки и столбцы.
5. Создание матриц для умножения:
matrix_x = пр.array([[1, 2], [3, 4]])
matrix у = np.array([[5, 6], (7, 8]])
Создаем двумерные матрицы: matrix x и matrix y, которые будут исполь-
зоваться в операции умножения. Каждая имеет размер 2x2.
6. Умножение .матриц:
matrix_product = пр.dot(matrix^x, matrix у)
Применяем функцию np.dotO для выполнения матричного умножения
matnx_x на matrix_y. Результат сохраняем в переменной matrix product. Эта
функция производит стандартные матричные операции, которые требуют
соблюдения правила размерностей (число столбцов в первой матрице долж-
но совпадать с количеством строк во второй).
7. Вывод произведения матриц:
print("Произведение матриц:\п", matrix_product)
Используем print () для отображения результата матричного умножения,
чтобы увидеть, как меняются значения в результате умножения.
Мы изучили, как изменять форму массивов и выполнять транспониро-
вание, а также как осуществлять матричные операции в NumPy. Эти навыки
важны для работы с многомерными массивами и матрицами, особенно в кон-
тексте линейной алгебры, которая широко используется в различных областях,
таких как статистика, обработка изображений и машинное обучение. Библио-
тека NumPy значительно упрощает выполнение этих операций в Python.
Я 7. Изменение t )рмы и ТрЗНСПОНиривзНИе
reshaped_array np.reshape(array_a, (3, 1)) S изменение формы на вертикальный вектор
рг1пТ("Иаменённый массив (с двумя измерениями):\n", reshapedarray)
Я Транспонирование двумерного массива
transposed matrix = matrix.Т
print("Транспонированная матрица:\n", transposed_matrix)
Я 8. Матричные операции
matrixx • пр.аггау([[1, 2], [3, 4)])
matrix_y • np.array([[5, 6], [7, 8)])
я Умножение матриц
matrix_product np.dot(matrix_x, matrix_y)
print("npoM3BefleHHe матриц:\п", matrix_product)
Изменённый массив (с двумя измерениями):
([3]
IbJ
[9]]
Транспонированная матрица:
1(1 4 7]
|2 5 8]
|3 6 Я]]
Произведение матриц:
1(19 22]
(43 50]]
Рис. 10.10
Этап 9. Работа с недостающими данными в NumPy
На этом этапе мы изучим, как работать с недостающими данными и зна-
чение NaN (Not a Number) в NumPy. Мы научимся игнорировать значения
NaN при выполнении операций, например суммы. Это важно, потому что
в данных могут встречаться недостающие значения и их нужно обрабаты-
вать корректно.
1. Создание массива с недостающими данными:
data with_nan = np.array([1, 2, np.nan, 4])
Создаем одномерный массив data_with_nan, который содержит значения
1, 2, np.nan (недостающее значение) и 4. Используем np.nan для обозначения
недостающего значения, что может произойти в реальных данных при сборе
информации.
2. Вывод массива с NaN:
print("Массив с NaN:", data with_nan)
Используем print () для отображения массива с недостающим значением,
чтобы увидеть, как оно включено в массив.
3. Вычисление суммы с игнорированием NaN:
sum_without_nan = np.nansum(data with nan)
Применяем функцию np.nansumO для вычисления суммы элементов мас-
сива data with nan, игнорируя значения NaN. Она суммирует все числа в мас-
сиве, пропуская недостающие значения, что позволяет избежать их влияния
на общую сумму.
4. Вывод суммы без NaN:
print ("Сумма без NaN:", surr. without_nan)
С помощью функции print () выводим результат суммы, вычисленной без
учета недостающих значений. Это позволит увидеть корректное суммарное
значение из оставшихся чисел.
Мы изучили, как работать с массивами, содержащими недостающие дан-
ные, и как корректно выполнять арифметические операции, игнорируя эти
значения. Это критически важный навык в анализе данных, поскольку данные
из реального мира часто содержат пропуски или ошибки. Используя функции
NumPy, такие как np.nansumO, мы можем эффективно обрабатывать такие си-
туации без необходимости предварительно очищать данные. Таким образом,
работа с недостающими данными становится гораздо проще и надежнее.
Изменённый массив (с двумя измерениями):
Транспонированная матрица:
Ц1 4 Ц
(2 5 8]
Р Ь 9Ц
Произведение матриц:
[(19 22]
[43 S0J]
-------------------------------------------------------—------------------------------------------ф 4- 0 :
Q а 9. Функции для работы с недостающими данными |
datawith пап • пр.аггау((1, 2, пр.пап, 4])
print("MaccMB с NaN:", data_with_nan)
# Сумма с игнорированием NaN
sua_without_nan • np.nansum(data_with_nan)
print("Сумма без NaN:”, sum_without_nan)
••• Массив c NaN: (1. 2- пап 4.]
Сумма без NaN: 7.0
# 1G, Сохранение и загрузка масс иgoo
Рис. 10.11
Этап 10. Сохранение и загрузка массивов в NuinPy
На этом этапе мы изучим, как сохранять массивы в файл и загружать их
обратно с использованием функций NumPy. Это позволяет сохранять ре-
зультаты работы программы и возвращаться к ним позже без необходимости
повторной генерации данных.
1. Сохранение массива в файл:
np.savef'original_array.npy', vector) ♦ сохраняем массив
Используем функцию np.save() для сохранения массива vector в файл
с именем original array.пру>. Формат мру — это стандартный формат
NumPy для хранения массивов. Он сохраняет не только данные, но и инфор-
мацию о форме и типе массива.
2. Загрузка массива из файла:
loaded vector = пр.load('original array.пру') if загружаем массив
Применяем функцию пр.load() для загрузки массива из файла 'origir.al_
array.пру'. Загруженный массив сохраняется в переменной loaded_vector,
и теперь мы можем использовать его в дальнейшем анализе или вычислениях.
3. Вывод загруженного массива:
print("Загруженный массив:", loaded_vector)
Используем print () для отображения загруженного массива на экран. Так
мы удостоверимся, что данные были корректно сохранены и загружены.
Мы изучили, как сохранять и загружать массивы с помощью функций
NumPy. Это очень полезная возможность для сохранения промежуточных
результатов работы, а также для обмена данными между различными про-
граммами или сессиями. Методы np.save() и пр.load() обеспечивают про-
стоту и эффективность, позволяя разработчикам легко управлять своими
данными в формате, оптимизированном для NumPy. Это особенно важно
в научных вычислениях и анализе данных, где работа с большими объемами
информации обычное дело.
Массив с NaN: [1. 2. nan 4.]
Сумма без NaN: 7.0
------------------------------------------------------------------------------------------------ ф Ф 0
О • 10. Сохранение и загрузка массивов
np.save(*original_array.npy*, vector) л сохраняем массив
loadpdyector • np.load( 1 originslarray.пру' ) ft за: ружаем массив
print("Загруженный массив:", loaded_vector)|
••• Загруженный массив: 100
• 11. Генерация случайных данных
normal_random_array • пр.random.normal(loc-0, scale-1, size-(4, 4)) ft массив из нормального распределения
print("Случайный массив с нормальным распределением:\п", normal randomarray)
ft 12. Линейная алгебра
v np.array([3, 4])
nanny - пр.1inalg.norm(v) ft длина вектора
print("Длина вектора:", norm_v)
ft 13. Гистограмма
import matplotlib.pyplot as pit
Рис. 10.12
Этан 11. Генерация случайных данных в NumPy
На этом этапе мы будем генерировать массив случайных данных, исполь-
зуя нормальное распределение. Это одно из самых распространенных рас-
пределений в статистике, которое применяется во многих областях, включая
научные исследования и машинное обучение.
1. Генерация массива случайных данных с нормальным распределением:
normal_random_array = np.random.normal(1ос=0, scale=l, size=(4, 4)) f
массив из нормального распределения
Используем функцию np.random.normal() для генерации двумерного мас-
сива normal_random_array, который состоит из случайных чисел, распределен
ных по нормальному закону. Параметры функции:
• 1ос=С — это среднее значение (математическое ожидание) распределе-
ния;
• scale=l — это стандартное отклонение, которое определяет разброс
данных;
• size= (4, 4) — это размеры массива, где мы создаем массив 4x4.
Функция возвращает массив, содержащий случайные числа, распределен-
ные оптимальным образом вокруг заданного среднего.
2. Вывод случайного массива с нормальным распределением:
print("Случайный массив с нормальным распределением:\n", normal_randcm_
array)
С помощью функции print () выводим массив normal_random_array на эк-
ран. Это позволяет увидеть сгенерированные данные и убедиться, что они
имеют нормальное распределение.
Загруженный массив: 100
.--------------------------------------------------------------------------------------------------ф Ф 0 :
О «11. Генерация случайных данных
потна l_rando«i array • пр.random.nor»al(loc-0, scale-1, size-(4, 4)) в массив из нормального распределения
print("Случайный массив с нормальным распределением:\n", nornial_randomarray)
... Случайный массив с нормальным распределением:
[(0.18516523 -1.5928028 -1.41495261 -2.59314618]
[-0.56261348 2.2782487 -1.28794739 -2.63143188]
[ 0.96266892 2.36371787 0.29792107 0.28873239]
[0.30988207 1.79425723 -1.45071192 0.31675333))
4 12. Линейная алгебра
v - пр.аггау([3, 4])
normv « пр.linalg.nora(v) 9 длина вектора
pr int("Длина вектора:", nor«_v)
8 13. Гистограмма
import matplotlib-pyplot as pit
8 Генерация случайных данных для гистограммы
data пр.random.normal(0, 1, 1000)
pit.hist(data, bins-30, alpha-0.7, color-’blue’)
pit.title('Гистограмма случайных данных’)
Мы изучили, как генерировать случайные данные с нормальным рас-
пределением с помощью функции пр.random.normal() в NumPy. Это умение
полезно в различных задачах, таких как моделирование, тестирование алго-
ритмов, создание синтетических наборов данных и статистический анализ.
Нормальное распределение — основное понятие в статистике, и его исполь-
зование объясняет многие механизмы в реальных данных, что делает этот
этап важным инструментом для аналитиков и исследователей.
Этап 12. Линейная алгебра в NumPy
На этом этапе мы изучим, как работать с базовыми концепциями линей-
ной алгебры в NumPy, включая вычисление длины вектора. Длина вектора,
также известная как его норма, представляет собой меру расстояния от нача-
ла координат до конечной точки вектора.
1. Определение вектора:
v = пр.array([3, 4])
Создаем одномерный массив v, который представляет собой вектор с эле-
ментами 3 и 4.
2. Вычисление длины вектора (нормы):
ncrm v = np.linalg.norm(v) т длина вектора
Используем функцию np.linalg.norm() для вычисления длины вектора v.
Эта функция вычисляет эвклидово расстояние (норму) вектора, что является
корнем суммы квадратов его компонентов.
3. Вывод длины вектора:
print("Длина вектора:", norm v)
С помощью print () выводим длину вектора на экран, чтобы убедиться,
что значение было вычислено правильно.
Этап 13. Гистограмма случайных данных
На этом этапе мы изучим, как строить гистограммы для визуализации
распределения данных. Используем библиотеку Matplotlib для создания гра-
фиков, что позволит удобно представить информацию.
1. Импортирование библиотеки Matplotlib:
import matplotlib.pyplot as pit * Импортируем библиотеку для построения
графиков
Импортируем модуль pyplot из библиотеки Matplotlib, чтобы использо-
вать функции для создания графиков и визуализации данных.
2. Генерация случайных данных для гистограммы:
data = пр.random.normal(0, 1, 1000)
Используем функцию пр.random.normal() для генерации 1000 случай-
ных данных, распределенных по нормальному закону с средним 0 и стан-
даргным отклонением 1. Эти данные будут использованы для построения
гистограммы.
3. Создание гистограммы:
pit.hist(data, bins=30, alpha=0.7, color='blue')
Применяем функцию pit.hist() для построения гистограммы на основе
сгенерированных данных. Параметры:
• bins=3C — количество столбиков (интервалов) на гистограмме;
• alpha=O. 7 — уровень прозрачности столбиков;
• color= >blue > — цвет столбиков.
4. Настройка заголовка и меток осей:
pit.title('Гистограмма случайных данных'}
plt.xlabel('Значение')
pit.ylabel('Частота')
Настраиваем заголовок и метки осей для гистограммы, чтобы сделать гра-
фик более информативным.
5. Отображение гистограммы:
pit.show()
Используем pit. show () для отображения построенной гистограммы на эк-
ране, чтобы визуально оценить распределение случайных данных.
Q * 12. Линейная алгебра
v - np. array (р, 4])
nor«_v • np.1inalg.nore(v) « длина вектора
print("Длина вектора:", nor«_v)
13. Гистограмма
import Mt plot lib. pyp lot as pit
• Генерация случайных дж>ых для гистограмм
data • пр.rando«.nor*al(0, 1, 1664»)
pit.hist(data, bins-36, alpha-6.7, color-'blue’)
pit .title('Гистограмм случайных данных*)
pit.xlabel(’Значение’)
pit.уlabel('Частота')
plt.sh<M()
100
Длина вектора: 5.6
Г исто1рзмма случайных данных
-3
2 3
Значение
РИС. 10.14
Мы изучили основы линейной алгебры в NumPy, включая вычисление
длины вектора, а также научились строить гистограммы с помощью Matplotlib
для визуализации случайных данных. Понимание линейной алгебры важно
в научных исследованиях и машинном обучении, в то время как визуализа-
ция данных помогает анализировать и представлять информацию наглядно,
что важно для обработки данных и аналитики.
Библиотека Pandas: инструменты для анализа
табличных данных
Pandas [97] предоставляет высокоуровневые структуры данных, такие как
Series и DataFrame, для эффективного анализа и манипуляции табличными
данными. Это делает Pandas незаменимым инструментом для исследователей
и аналитиков, работающих с большими объемами данных.
Основные возможности Pandas
Установка и импортирование библиотеки Pandas
Установим библиотеку Pandas, если она еще не установлена, и импортируем
необходимые библиотеки. Pandas — это мощная библиотека для анализа дан-
ных в Python. Импортируем также и библиотеку NumPy, которая обеспечива-
ет поддержку массивов и позволяет выполнять математические операции.
1. Установка библиотеки Pandas:
!pip install pandas
Устанавливаем библиотеку Pandas в среде Google Colab или Jupyter Notebook.
Команда ! перед рср позволяет выполнять shell-команды из ячейки Python. Ус-
тановка библиотеки необходима, если она отсутствует в текущей среде.
2. Импортирование необходимых библиотек:
import pandas as pd
import numpy as np
Импортируем библиотеку Pandas под псевдонимом pa, чтобы упростить
обращение к ее функциям. Импортируем библиотеку NumPy под псевдони-
мом пр для работы с массивами и математическими операциями. Они часто
используются в связке, так как DataFrame в Pandas строится на основах мас-
сивов NumPy.
На этом этапе мы уже готовы использовать Pandas и NumPy для анали-
за и обработки данных. Убедившись, что обе библиотеки установлены и им-
портированы, мы можем перейти к более сложным операциям — созданию
DataFrame, работе с недостающими данными, фильтрации и т. д. Этап уста-
новки и импорта — основной для дальнейшей работы с данными в Python.
Q ipjp ₽* *«d«|
Nrquimant alrrndy *ati»fl«d: panda* Ln /u*r/local/Iib/pythenS.12/di*t-pnckag«« (>.2.2)
Rvquircmnt already *etl»fi*4: пм»ру>-1,2*.* in /u»r> ioc*l/llb/pythonJ.ll/di»tpark*<e» (free panda*) (2.9.2)
Requirement already satisfied: python datautil>-2.8.2 la /usr/locaa/llb/pythenJ.iVdlit package* (frw pandas) (2.9.8.po»td)
Requlramcnt already satisfied: pytr>-»29.1 in /u«r/I*cai/lLb/python). 12/dl*t-package* (free pandas) (2925.2)
Requirement already taxi*fled: t£dat*>-2822.7 in /v*r/tocal/lU/pyth«n$.12/dUvpackage* (free panda*) (2935.9)
Require***! already satisfied; *1к»1Л in /w/ioc»i/ilb/pytban>.12/di*t-pa<k*ge* (few pythen-da*e»rtilx2.9.2->panda*) (1.17.9)
lapart panda* at pd
Import raa^y a* np
data {
'Han': ('Ам*', 'бфос*, 'вмтер*, 'Галта'],
’•aipacT'j (28, Э2, гф.плп, 29],
* Горо* ‘: I'nxiM', ‘Санкт-Петербург*, 'Гавана', ‘(«атерннбург '],
' Заработная плата': (75990, ВТМО, пр.мп, 67068]
}
• 1. Спмампе Oat а» ram «•> слааарп
data - (
№м ; [ Im', 'корне*, ’бметор*, ‘Главна*),
*8оараст': (28, », пр.пап» 29],
’Гарцд’: ('*х«аа*, 'Сам* Петербург °, ’Казат*, 'екатермбург * ],
Заработная плота*i (75999, «2998, np.nan, *7090)
df • pd.Oatafram(data)
prlat(~CoW tii Oetafraac: V»". df)
Рис. 10.15
Создание DataFrame из словаря
Создадим DataFrame с помощью словаря. DataFrame — основная струк-
тура данных в библиотеке Pandas, которая позволяет работать с таблицами,
содержащими данные различных типов.
1. Создание словаря с данными:
data = {
'Имя': ['Анна', 'Борис', 'Виктор', 'Галина'],
'Возраст': [28, 32, np.nan, 29],
'Город': ['Москва', 'Санкт-Петербург', 'Казань', 'Екатеринбург'],
'Заработная плата': [75000, 82000, np.nan, 670С0]
}
Определяем переменную data — словарь, содержащий четыре ключа:
<Имя>, 'Возраст', 'Город' и 'Заработная плата'. Их значения представляют со-
бой списки, состоящие из данных. Для количества зарплат и возраста исполь-
зуется np.nan, чтобы обозначить недостающие данные.
2. Создание DataFrame из словаря:
df = pd.DataFrame(data)
С помощью функции pd. DataFrame () создаем объект DataFrame df, переда-
вая в него наш словарь data. Каждый ключ становится столбцом в DataFrame,
а значения списков становятся соответствующими строками.
3. Вывод созданного DataFrame:
print("Созданный DataFrame:\n", df)
Используем функцию print]) для отображения созданного DataFrame на
экране. Это помогает подтвердить, что DataFrame был успешно создан, и мы
можем увидеть структуру данных, с которыми будем работать в дальнейшем.
На этом эт ане мы успешно создали DataFrame из словаря, который содержит
информацию о сотрудниках, включая их имя, возраст, город проживания и за-
работную плату. Создание DataFrame — это важный шаг в предварительной об-
работке данных, так как позволяет структурировать информацию для дальней-
шего анализа и манипуляции. Теперь мы готовы использовать этот DataFrame
для различных операций, таких как анализ, визуализация и обработка данных.
Яе* *«Дгемт «1ге**у «atlifledi Modas И /м*г/local/lib/руОчлЗ.
8«**Cre*<nt alrtndy «atlsflodi амру»-1.26.• in /u*r/loc*l/Ut»/pyXhor J.12/dist-f>*<k*d** (fro* panda*) (2.6.2)
e*q*lr***nt «Irpndy »ati*fi*d: python-datooCll*«3.d.2 In /wr/local/lib/pjrtbonj.ia/aHx-packagei (free panda*) (2-*.*-po»t*)
«MftdrwMnt already utitfiad: pytz>-»2*.l i* /и*г/1ос*1/11&/ру<Ъ9л3.12/<*11хрмка<«* (fro* p*>»dai) (2*25.2)
already *«ti*fi*d: t;dataX2*22.7 in /u**7local/Hb/pyt*>onj.l2/dUt-p»ck*de* (fr^i panda*) (2*25.2)
Re*dSr«*«nt already »*cl*fi«di *1m>-15 tn /м*г/local/lib/pythonJ. 12/di»t-pack*gei (fro* pyxhe*dacevrjl>-l.».2->p**4»») (1.17.*)
0 tapert panda* а* рЦ
laport мару ас np
data • (
(*Аии*', 'Bop*c'( ‘*>*rof>‘, *Галж*']г
'BoapaCt'c [2d, Э2, np.nad, 2*],
’Город'i [‘Косжад', 'Саижт-Петербург’, 'ими*', 'Счатерамбург'
Japadennaa «шаг*': [75*0*. *299*. ар.nan, *7999}
)
• I. С*1Л*и** Oatafra«e а* сдемра
data • <
'*•’* ['Яш', 'dopac', •8amop*, 'Гаммы* J,
'Ямраст'з [28, 32. пр.пал, 2d].
Торо*'। ['пх«м', Чаи»»-Петербург', 'Кт**', Чсатера^ург),
Заработная мата*: £75*99. Я2«*9, ар.пал, 47М»)
)
df * M-tettFraMfdata)
print (‘Cowaiwari D*t*fraaa:\»*, df)
••• Сомами*** Datafraee:
**a doapacr город 5apa6on-*a плат*
• Ама 2».* Носжаа 73*99.9
1 Борне Э2.9 Санст'Петербург 829*9.9
2 Рнктрр ММ Каааиа ММ
2 гадина 29.9 с«ат«ранбур< «7999.9
0 9 2. Ofwamie омрацм с Oatafraae
рг1п(('\линборм*чмл 9 QataFraa*:*)
prInt(df.Info ))
pc Int ("Упстатгастаческо* ол»с*>а>е pata*raaa:\)«", df-dateriba Г )
• J. №чн*сацпв a in*эр д«м>ш*
Рис. 10.16
Основные операции с DataFrame
Выполним основные операции с DataFrame, чтобы получить информацию
о его структуре и содержимом. Так мы лучше поймем данные, с которыми
работаем.
1. Получение информации о DataFrame:
print("\пИнформация с DataFrame:")
print(df.info())
Мы используем метод info() для получения информации о DataFrame.
Этот метод выводит:
• общее количество записей (строк);
• количество столбцов;
• информацию о типах данных в каждом столбце (например, int64,
float64, object и т. д.);
• количество ненулевых значений в каждом столбце.
Это помогает быстро оценить структуру данных, выявить наличие про-
пусков и понять, какие типы данных мы имеем в DataFrame.
2. Статистическое описание DataFrame:
print("ХпСтатистическое описание DataFrame:\n", df.describeО)
Используем метод described для получения статистического описания
числовых данных в DataFrame. Этот метод предоставляет:
• количество (count) ненулевых значений в каждом числовом столбце;
• среднее значение (mean), стандартное отклонение (std), минимальное
(min) и максимальное (max) значения;
• 25-й, 50-й (мед)апе) и 75-й процентиль (25 %, 50 %, 75 %).
Эти статистики помогают понять распределение числовых данных, вы-
явить возможные аномалии и дать общее представление о данных.
На этом этапе мы выполнили основные операции, позволяющие изучить
DataFrame и его содержимое. Использование методов into() и described —
это первый шаг к анализу данных, который позволяет оценить их целост-
ность и структуру. Это знание важно для дальнейшей обработки данных
и принятия решений при анализе. Понимание этих основ является ключевым
для успешной работы с Pandas и анализа данных в целом.
Им »Эр«СТ Город
• 2* *.Ф Иэскм
1 Борис И.Ф С»и«ст-Петербург
2 Виктор
3 Галима 2Ф.Ф Содтеримбург
Заработай плата
ТБвОФ.Ф
Л29О9.9
бтффф.ф
Q а 2 Осиовме тераом с DataFraae
print (‘спИнфородци» о Owtefг«ае:’)
print(df.Info;))
print("клСтатистическое опасение Patafraaa;\n‘, df.describef>)
Ннрормациа о Datafraae!
«less 'p*Maa.«oe«.fr-aae.OatafeaM*>
HanftlndeM! 4 ««tries, «Mi
Data coluans (total 4 colwam):
Col«w Man* Mal I Count
• Ими 4 ncn-aull
t Boapacv 9
2 Город * noeu oull
3 Эаработмао плата 9 пеп*аы11
dtypesi float» (2), object(2)
eeory useget 24Ф.Ф+ byte»
Mona
otype
object
float»
GtJect
float»
Стдтис v«wc«oa олысаиид Oatafram
fteopMT Заработм мата
count 9-ШМП >.*МФФ*
can 2».«4»7 746M.M«»7
). «чмксаиис и ea^op данмвс
print ( *\пб*4ор «ДИОГО столбил (Jorian):’)
prlnt(df [’MT ])
print(*\лф«4ор столби»;*)
Рис. 10.17
Индексация и выбор данных
Исследуем методы индексации и выборки данных из DataFrame. Эти опе-
рации позволяют извлекать необходимые данные и работать с ними более
эффективно.
1. Выбор одного столбца (Series):
print("\г.Вьсбор одного столбца (Series):")
print(df['Имя'])
Используем синтаксис df [<Имя >] для извлечения данных из столбца <Имя >
нашего DataFrame. Этот метод возвращает объект Series, который содержит
все значения из указанного столбца. В каждом случае будет выведен список
имен сотрудников.
2. Выбор нескольких столбцов:
print("\г.Выбор нескольких столбцов:")
print(df[['Имя', 'Возраст']])
Для выбора нескольких: столбцов используем двойные квадратные скоб-
ки: df [ [< Имя >, < Возраст >] ]. Это позволяет извлечь сразу несколько столбцов
и вернуть новый DataFrame, который будет содержать только указанные стол-
бцы. В данном случае мы получим DataFrame с именами и возрастами сотруд-
ников.
3. Выбор данных по условию (возраст больше 30):
print ("\г.Выбор данных пэ условию (возраст больше 30):")
print(df[df['Возраст'] > ЗС])
Для фильтрации данных по условию используем логическое выраже-
ние: df [< Возраст >] > 30. Это условие позволяет выбрать только те стро-
ки, где возраст сотрудников превышает 30 лет. Результатом будет новый
DataFrame, содержащий только тех сотрудников, которые соответствуют
этому условию.
На этом этапе мы изучили методы индексации и выборки данных из
DataFrame. Выбор данных по столбцам и условиям — это важный аспект ра-
боты с данными в Pandas, поскольку он извлекает необходимые сведения для
дальнейшего анализа.
Эти операции помогут нам более эффективно работать с большими набо-
рами данных и сосредоточиться на той информации, которая наиболее ак-
туальна для анализа. Понимание индексации — ключевая компетенция для
работы с библиотекой Pandas.
• ♦. Сврабадг»* abihbw
print('ЧпЗвтимчк пропусков в ’•озрвсг' средркмч зявмеппея-.")
в tw-тслжм tpcjpwe зпочепме возрвкзв (иешмчая Май)
в*еев^с_а<е • 'Возрос?').аеов()
Обработка недостающих данных
Поработаем с недостающими данными в DataFrame, заполним пропуски
в столбце < Возраст > средним значением. Это поможет избежать проблем при
анализе данных, связанных с отсутствующими значениями.
1. Вывод сообщения о заполнении пропусков:
print("\г.3алолнение пропусков в 'Возраст' средним значением:")
Используем функцию print () для вывода сообщения, информирующего,
что мы собираемся заполнить пропущенные значения в столбце < Возраст >.
2. Вычисление среднего значения:
average_age = df['Возраст'].mean()
Вычисляем среднее значение для столбца < Возраст >, исключая недостающие
значения (NaN) с помощью df [ 'Возраст' ] .mean (). Сохраняем это значение в пе-
ременной average age, чтобы затем использовать его для заполнения пропусков.
3. Заполнение пропусков в столбце 'Возраст':
df['Возраст'] = df['Всзраст'].fillna(average_age)
Используем метод fillna () для заполнения всех NaN в столбце < Всзраст >
средним значением, сохранив результат в этом же столбце. Этот шаг гаран-
тирует, что теперь в столбце < Возраст > не остается недостающих данных, что
важно для корректного анализа и обработки.
4. Вывод обновленного DataFrame:
print (df)
После выполнения всех операций выводим обновленный DataFrame на эк-
ран. Это поможет нам убедиться, что все пропуски в столбце < Возраст > были
успешно заполнены средним значением, и мы можем увидеть весь изменен-
ный набор данных.
2 Виктор ММ
J Галии» 29. •
*Мооша_стол6ец' J • «('Заработная ддата*) * 6.13 • 13Х от мрляати
print ('ХлДобааяетмЭ столбец ’ИоемЛ.стоябеи' i\n”,
В В. уд*лнныи
'и-|»|1_<то*бач' ]. iaplace-Trua)
print("СлОаТвГгаит мосде удаления ’Мооай.столбсч*, «)
У. Соргнроакд да мд
print('ЛлСортирома дш i»ti по ооар*сту!'г «)
рг int («. sort .value»; By- ’ Bospac r ‘)
На этом этапе мы успешно обработали недостающие данные в нашем
DataFrame, заполнив пропуски в столбце 'Возраст' средним значением. Уп-
равление пропущенными значениями важно для анализа данных, так как
качество данных напрямую влияет на точность выводов. Заполнение пропус-
ков помогает обеспечить целостность и полноту используемых данных для
дальнейшего анализа. Теперь мы имеем обновленный набор данных, готовый
к использованию для более глубоких аналитических задач.
Добавление новых столбцов
Добавим новый столбец в наш DataFrame. Это может быть полезно для
создания новых производных данных, которые помогут в анализе. В данном
случае добавим столбец, представляющий собой 15 % от заработной платы
сотрудников.
1. Добавление нового столбца:
df['Новый_столбец'] = df['Заработная плата'] * 0.15 # 15% от зарплаты
Используя синтаксис df (< Новый столбец >], мы создаем новый столбец под
именем '.Новый_столбец'. В качестве значений рассчитываем 15 % от каждого
значения в столбце 'Заработная плата' с помощью выражения df (< Заработная
плата >]*0.15. Это позволяет быстро получать дополнительные данные, ос-
нованные на существующих значениях, без необходимости манипулировать
данными отдельно.
2. Вывод обновленного DataFrame:
print("\пДобавленный столбец 'Новый_столбец':\n", df)
После добавления нового столбца используем функцию print () для выво-
да обновленного DataFrame, чтобы увидеть изменения. Так мы проверим, что
новый столбец был успешно добавлен и содержит ожидаемые значения (15 %
от заработной платы).
На этом этапе мы успешно добавили новый столбец в наш DataFrame, ко-
торый представляет собой 15 % от заработной платы сотрудников. Это по-
казывает, как можно создавать дополнительные производные поля на осно-
ве уже имеющихся данных для более глубокого анализа. Добавление новых
столбцов — ключевая операция, позволяющая расширять и улучшать анализ
данных, обеспечивая доступ к новым вычисленным метрикам, которые мо-
гут быть полезными в дальнейшем.
*•« 0М04СТ Орал ПЛАТ*
• Аж* г». 040460 *Х<М 75900.0
1 Борис ».444444 Самет-Петербург КООО,•
2 Вектор 29.М000? Каэаеь НаМ
1 Галин» 20.000040 Гс«теренбур« *7000.0
Q Ао4мл*ни« ноамж столбим
<И[ •но.иО сголбеч'] . 4Г[‘Зар«ботмм «мт» ] • 0.2» • 15» от м*>шгЦ
рг!м('мММО0л«мга«* <*мв*ц 'мем.стфйвоц'До'. Of)
Добавленный столбои Но*ы»_<тохб<ц'•
им во» рост Город
О Ажа 2*.040400 Иккм
1 борее >2.000000 СжгтПгт.рбург
2 Вектор 29.М4667 Ка>*н»
S Галена 20.040040 (слтаренбург
Мроботкоа плота ио4ы*_€тоа0*ц
75000.0 11250.0
•2000.0 12)00.0
мам Кай
*7000.0 10050.0
а *. Удееажв стсмбчо»
6f.0rap(eelu«»n4*[ 'нмы*_с голбец ° ], inpl»c«*Tru«)
print(*\nOataFraea *осл* удалена» *Hoai >_столб*ц'j\n-, 0f)
а 7. Сортировка ju him
print(*\лСОртиро*к* Al I Ml no ooapocry;', Of j
pr int ( Of. »ort_v*lue* (by-" Ooapai т')j
print(*1лГруппнро«са ас 'Город' £ ммклвянвн epejprero:\n“, grouped_nr*n)
a 9. Экспорт данных; • CSV
d<.to_c»v( *0*plo)re*»_Mrtp<jt. c*v’, i*4ex«'»ls£)
print (*V<O*t*rroe* мемортироваи * *ee?)oye«»_outpvt .<•**")
10. Затру»«a A*mw» m CSV
leMMtf - pd.re*4_ciw(’eaployees_e»<tp<rt.c*v')
print(' v*3arpy»*n^ai OotaFraM aa CSViW» Loaoed.Of)
Рис. 10.20
Удаление столбцов
Удалим ненужный столбец из нашего DataFrame. Это полезно, если один из
столбцов больше не нужен для анализа или его значения дублируют другую
информацию.
1. Удаление столбца.
df.drop(columns=['Новый_стслбец'], inplace=True)
Используем метод drop() для удаления столбца <Новый столбец) из
DataFrame. Передаем аргумент со1итпз=(<Новыи_столбец>], чтобы указать, ка-
кой именно столбец хотим удалить. Параметр inplace=True указывает на го,
что изменения должны быть применены в исходном DataFrame, а нс во вновь
созданном объекте, что позволяет сохранить оригинальный экземпляр без
указанных данных.
2. Вывод обновленного DataFrame:
print ("V.DataFrame после удаления 'Новый_столбец':\n", df)
После удаления столбца выводим обновленный DataFrame для того, чтобы
удостовериться, что <Новый_столбец> был успешно удален. Это также позво-
ляет проверить структуру и содержимое DataFrame после изменений, а также
убедиться, что остальные данные остались нетронутыми.
На этом этапе мы успешно удалили ненужный столбец < Новый_столбец >
из нашего DataFrame. Удаление столбцов — это важная операция при обра-
ботке и анализе данных, позволяющая очистить набор данных от избыточ-
ной или ненужной информации. Понимание того, как управлять столб-
цами в DataFrame, помогает поддерживать данные в актуальном состоянии
и повышает эффективность анализа, позволяя сосредоточиться только на
самой ценной информации. Теперь у нас есть обновленный DataFrame, содер-
жащий только необходимые данные для дальнейшего анализа.
1 порам и.ммаям -<*repcypr
2 Вмстер 2«.«ММ2 Кв»ахъ
3 Гжляш 29. МгМбб Сяжтврйибург
« 7. Сортировал < шм
print(*\пСортирОв<* МИИМС по totpKTy;", af)
print(<Н. tortjvtloes fbr*' божркт 1'))
•. <руппиропал Дак I
frwp<d_«e«n - 4f.froupbyCГород').netnfnuoei-ic.enly^Truc) (p«>w nt городом
prlntOnrpynnnponcB no Город" с мгаисленгев средмгоЛп-, (гоореб.мвп)
« ». Экспорт дамам* • CSV
4f. to_<*v( * eep lo»*e»_o»rt put. c iv *, in4*x»Fel **)
prlntCXnOoteFraee мспортврооач « *«eploye*»_o«tp*t .<»*'*)
• It- Зогруакд да111 m CSV
lotneddf - pd.r*td_c*v('Mploy«e*_output.eiv')
print ('^n3trpymwW 0«t«*r*te <> CSV! in", IjWetpfj
11. Сомам»* я работ* c Serie»
M^ort.urlet • Зв, M, 40, И]. ne»t-’‘*cnt')
printС\пСо*дамм** SerieMbtr*_»*eie*)
print (а\пСуммв >а«мгмтов Serie»:’, 1шЫг«мгк».1м())
print ('Среднее >w».r»—e Strits:". «M6tr*_*tri*«.etM())
Рис. 10.21
Сортировка данных
Рассортируем данные в нашем DataFrame по определенному столбцу. Сор-
тировка помогает упорядочить данные для более удобного анализа и пред-
ставления информации. В данном случае мы будем сортировать DataFrame по
возрасту сотрудников.
1. Вывод сообщения о сортировке:
print("\пСортировка по возрасту:")
Используем функцию print () для вывода сообщения, информирующего,
что мы собираемся сортировать данные по возрасту. Это поможет задавать
контекст для следующей операции.
2. Сортировка данных по столбцу 'Возраст':
print(df.sort values(by='Возраст'))
Вызываем метод sort values () на нашем DataFrame и передаем аргумент
Ьу= >Возраст >, чтобы указать, что хотим отсортировать данные именно по это-
му столбцу. Метод scrt_values () по умолчанию сортирует данные в порядке
возрастания. Результаты сразу выводятся на экран.
3. Вывод отсортированных данных.
Выводим результат сортировки с помощью print (), что позволяет сразу
увидеть, как изменилась структура данных после операции.
На этом этапе мы успешно отсортировали наш DataFrame по возрасту со-
трудников. Сортировка данных — важная операция при анализе, так как она
позволяет быстро находить и сравнивать значения. Упорядочивание данных
по ключевым столбцам помогает лучше понимать структуру набора данных
и выявлять закономерности. Теперь у нас есть отсортированный набор дан-
ных, который может быть полезен для дальнейшего анализа и принятия ре-
шений. Это знание о сортировке добавляет еще одну мощную возможность
в работу с библиотекой Pandas.
* ооряс x.aowv* * ч*якт ier«pe)rpr
2 Виктор 29.И9997 К«з*м*
) Галин* 29, WWW 1к*т«р*»б)грг
Нам
199t9.9
• A. wJ>nrtlirtl CTOfl6t|M
df .drepicolten»-, №wA_cInplaca-Tci*»)
pr!nt( "\r0*t«Fraa* поел* удалений 'г*Мм1_сгол6«ц':\п', dfj
OataFraea посла удалена* мзмй_; тв<*б«ц’ г
Нил Возраст Гор** Заработмал пяата
G Анна 28.М99М Косам 75999.9
г Варис ЗЗ.ООООМ Саикт-Петербург 82900.9
i Виктор 29.ММ67 НМ
3 Галина 29.999999 В кат «ри-бур, 67999.9
Q *7. Сартафва** дмаа
print (*\лСсртироакл данма по аотрасту:", df)
print(df.*ort_val«**»(by>'Возраст'))
Сертироака **н^я по возрасту; «На Во траст Город Заработной плат*
е Айн* 28.999999 Иосям 759*9.9
1 Борис 32.099999 сомит Петербург 82999.9
2 Виктор 29.699997 KOMfw Най
3 Галина и. 809009 (<«теркибург 67900.9
Мил возраст Город Зароботм** плата
в Ами* 29................ Иосям 75999.9
э Галин* гв.воооое ек*тер«мбург ьтоео.е
2 Виктор 29.699997 Козам* NaM
t Bop.. 52.090000 Саикт-Петербург 02999.9
» в. Групплроока даиюм
фпвк**9ввеап df.frovpby( 'Город' ).оеоп^пимг1с_оп1у*Тгве) а Средние моче—«я по городам
pr|At('V*rpywMpoaK* по ‘Город’ с а»««слеяеем среднeroi\п", fro«ped_*e«0
• 9. Экспорт Д*тмх • CSV
df.to_c3v( 'ee₽io-/eeT_output.c»v', Index'Falce)
prlnt(*V®ataFc*a« мсоортиромм a 'eoployect.outptft.ит”)
Рис. 10.22
Группировка данных
На этом этапе мы сгруппируем данные в нашем DataFrame по определенно-
му критерию и вычислим средние значения для каждой группы. Группировка
позволяет эффективно анализировать данные и получать сводные значения
по категориям. В данном случае мы будем группировать данные по городу
и вычислять средние значения для каждого города.
1. Группировка данных:
groupedjnean = df.groupby('Город').meanО ff Средние значения по городам
Используем метод groupby () на нашем DataFrame и передаем аргумент < Го-
род >, чтобы указать, что хотим группировать данные по этому столбцу. Затем
применяем метод mean(), который вычисляет средние значения для осталь-
ных числовых столбцов в каждой группе (в данном случае это будут средние
значения для 'Возраст' и 'Заработная плата'). Результат группировки и рас-
четов сохраняем в переменной grouped mean.
2. Вывод результатов группировки:
print("\пГруппировка по 'Город' с вычислением среднего:\n", grcupedjnean)
С помощью функции print () выводим результаты группировки на экран.
Это позволяет нам увидеть средние значения по каждому городу и оценить
различия между группами.
На этом этапе мы успешно сгруппировали данные по столбцу < Город >
и вычислили средние значения для каждого города. Группировка данных —
это мощный инструмент для анализа, который позволяет упрощать визуа-
лизацию больших объемов информации и выявлять статистические зако-
номерности. Использование метода groupbyO в сочетании с функциями
агрегирования (такими как mean ()) значительно улучшает наши возможнос-
ти по анализу данных и позволяет делать более обоснованные выводы. Те-
перь у нас есть сводная информация, которая поможет в дальнейшем анализе
и принятии решений.
2 Виктор 29.6ВЛ64У Кя*«и>
1 Борм 32 имев Самт-Петербург
0 • Группировке дшм»
grouped м»еп «Н-сгоирЬу. 'Город ).ме«л{пияег1.с_оп1у>Т1ти) • сре**е »нем»ния по городам
print(*\пгруппаррргв пр ‘Город' < емнисление* средмегртХп", grouped.Mean)
Груплдроакд по 'Город' с отчислением среднего:
Роердст )арвботнаа м«та
Город
Екатеринбург 29.»1>Ш «УМ».»
Каем 2Р.666М7 Май
Носква 28.MMW Г5«М.«
1*м«т-Петербург J2. «2«М.»
• ♦- Тнспирт дани» * CSV
.t«_c*v(’eMpleye*s_eutput.esv', 1л6ея-Г«1*е)
print('\nOataFrae* акспортяромч ’eaployee*_««tp*t .Csv'*)
» 1*. Загруака да । wi м CSV
leaded dt • pd.r»e4_«sv('Mploye*s_output.esv')
print(~\Магрум««*4 OataFгаме «s CSViXn", loade4_df)
11. Саадами» работа c Serie*
мм6ег*_мНе* - pd*S«r-i«*((l«, 2», 3», *•« S6]. я ‘«тела*)
print(‘ЧпСоадаяпал Serie*:\n”, ftier i_tc-lri 1
print(*\nCyw»a дламептов Serie»:*, nuafeers_»er 1*». 1um())
priet{*Cpcnnee значение Series:’. 1ммйег*_*ег1е».мем())
12. (фмменемпе бун«о*ш к кведому элементу а РаГдТгале
df[ ‘Поамменнап.ааработма«.плата' ] - t#f(‘заработкам плата*).applyHaatxJa ж: к • Х.1») • Увели <!»« дарллат» на 1«Х
print('ХлОаТаГгаме с применением ру»иао« для уаепчиения зарплат*’Хл*. df)
а 13. Слияние DataFraae
additional.data {
‘Город1; ('Мрсаеа*, ‘Саикт Петербург', 'Кааач»*, 'Влалпаостож'],
Рис. 10.23
Экспорт данных в CSV
Экспортируем данные из нашего DataFrame в файл формата CSV (Comma-
Separated Values). Экспорт данных позволяет сохранить анализируемую ин-
формацию для последующего использования или передачи другим пользо-
вателям. В данном случае мы экспортируем DataFrame, содержащий данные
о сотрудниках.
1. Экспорт данных в CSV:
df.to_csv('empLoyees_output.csv', index=False)
Используем метод to csv() на нашем DataFrame df для экспорта данных
в файл. Передаем аргумент < employees_output. csv > в качестве имени файла, в ко-
торый будут записаны данные. Указываем параметр index=False, чтобы при эк-
спорте не сохранять индексы строк DataFrame в выходном файле. Это позволяет
сделать его более компактным и обычно предпочтительным при работе с CSV.
2. Вывод сообщения об успешном экспорте:
print("V.DataFrame экспортирован в 'employees_output.csv'")
Используем функцию print () для вывода сообщения о том, что DataFrame
был успешно экспортирован в указанный файл. Это сообщение подтвержда-
ет, что операция прошла успешно и данные теперь находятся в файле, гото-
вом к использованию.
На этом этапе мы успешно экспортировали наш DataFrame в файл формата
CSV. Экспорт данных — важный шаг, позволяющий сохранить результаты
анализа и делать их доступными для других форматов и приложений. CSV —
распространенный формат для обмена данными, который может быть ис-
пользован в различных программах, включая Excel и системы баз данных.
Теперь у нас есть сохраненная версия данных в виде файла, которую можно
использовать для дальнейших манипуляций или анализа.
2 Виктор
1 Борис
».М4М7
Клзвнв
12.999999 Сжкт Петербург
Ж. Группировке дм но
grvw«6_e«4n - df.gr«ep6y('Город').ае«Нгцямг1с_от«1у*тгы») Средние «мнение <х> ородаи
print (‘хпГруппмрови но Город' с млчклеиавы сридмито \п“, |rouped_a»anj
Группировке до ‘Город* с —г едением среднего
возраст Хариботнаа они
Город
Екатеринбург ЗР.РРОРРв ОГвРв-в
казан» ЗЛ.99ЫЛ? ым
поскм гвееоевв гмм.в
Санкт-Петербург ЭЭ.вММв Е26М.6
df.'eeployee»_o*tput.csv", index-falie)
print(‘ллОаТаЗгаве ксяортироми в 'eopioyees_outpwt .<»*“)
Datafrene зксаортирован a ’oMplayeaa^output.civ*
> 2*. Эдгрузка даиии «с» CSV
loaded j»f - pd.r*ad_<»v(*eapiDyeet,*wtp«rt.c«v'}
prInt(‘ЧдЭагруиеиммЙ DataTraoe ив CSV1Ля*, looded,df)
11. Создание и работа c Series
п«м*ег>_мг1е» • pd.series((!•, 2d* », 5»:, даве-'^сла*)
print("ХлСоаданная Seriaitln", шаЬегв_вег1ев)
print ('ХяСумм алемемтоо Serie»!*, nen*ersw»erles.swBO)
prgntCCp«jv*ee внемеиме Serie*;", «шфег»_мг1е».аеап( )
12. f\ — ктиие румчаии к «алДйту адгаеиту a Oatafraar
df (’Лмм*ем«аязаработиаа олата' ] • df[ ‘Заработная пмта‘].арр1у(1шМа х: х • 1.1в) в Увеличение зарплаты на 1М
print(*\пЛаТаГгава вриивтнииаит» румпаии доя увели»Т1МД аарллатм.\а", df)
Рис. 10.24
Загрузка данных из CSV
Загрузим данные из ранее экспортированного файла формата CSV обрат-
но в DataFrame. Так мы сможем работать с сохраненными данными, анализи-
ровать или изменять их по мере необходимости.
1. Загрузка данных из CSV:
lcaded_df = pd.read_csv('employees_output.csv')
Используем функцию pd.read csv() из библиотеки Pandas для загруз-
ки данных из фай,та 'employees_output.csv' в новый DataFrame, названный
lcaded_df. Эта функция автоматически считывает данные из файла, интер-
претируя строки как записи и разделяя столбцы на основе запятых (по умол-
чанию). После выполнения этой команды DataFrame loaded df будет содер-
жать все данные, сохраненные в CSV-файле.
2. Вывод загруженного DataFrame:
print("\пЗагруженный DataFrame из CSV:\n", loaded df)
С помощью функции print () выводим содержимое загруженного DataFrame
на экран. Это позволяет нам убедиться, что данные были успешно загружены
и отражают содержимое исходного DataFrame до экспорта.
Мы успешно загрузили данные из CSV-файла в новый DataFrame. Процесс
загрузки данных — важный этап работы с данными, поскольку позволяет
восстановить информацию после экспортирования или получения данных
из внешних источников. Важность использования формата CSV заключается
в его универсальности и легкости в обращении. Теперь у нас есть доступ к за-
груженным данным, что позволяет продолжать анализ или изменения без
необходимости заново вводить информацию.
2 Рмтор ».6Ы«*7
1 Sop«C Н, WHW С*агг -Петербург
« ♦. Э«оорт даммс a CSV
tfr'•ptoytct^tvtpvC.ctv' ,
pr Lnt(*^/Oatafraaa мкпортмроаам a 'replojt»»putpvt.c»v'*)
Datafrae» аасаврт«р«ааи a 'aapl0y««t_eetput.eiv'
Ф * It, Mrpyxa > CSV
IsaMd .tff - pd.r«ad_<tv( *aaploywat_Mrtput.<«v')
prlntCDAlarp/Mcmwt DataFraae м CSViVT, )oade4_4f)
>агруа*н»а<1 DataFraaa a> CSV:
• It. Саадамае работа c Series
wbers.serles • pd.SeHe*( [It, 2», 5Р» *t, St], ямн'Чкм'>
p*-Ut("\nCp*M»«waa ku^O.ikI»»)
print(*\ftCy*w Maawfca Series:*, i^abers_sarlet)
pr Lnt(*Cp**«ee эначелае Serieti", >waters мг1е».амп41)
Рис. 10.25
Создание и работа с Series, применение функции к каждому элементу
в DataFrame
На этом этапе мы сначала создадим объект Series с помощью библиотеки
Pandas, а затем применим функцию к каждому элементу в столбце DataFrame.
Это мощный инструмент для работы с данными, который позволяет выпол-
нять вычисления и трансформации.
1. Создание Series:
numbers_series = pd.Series((10, 20, 30, 40, 50], пате='Числа')
print("ХпСозданная Series:\n", numbers series)
Используем pd.Series() для создания объекта Series, передавая список
чисел [10, 20, 30, 40, 50] в качестве данных. Задаем имя для Series с помо-
щью параметра name= >Числа >. Затем выводим созданный объект на экран для
проверки его содержимого.
2. Выполнение агрегирующих операций на Series:
print("\пСумма элементов Series:", numbers series.sum())
print("Среднее значение Series:", numbers_series.mean())
Применяем метод sum() к numbers_series, чтобы вычислить сумму всех
элементов и выводим результат на экран. Также применяем метод mean(),
чтобы вычислить среднее значение элементов Series и выводим это значе-
ние. Таким образом, мы демонстрируем базовые операции, которые можно
выполнять с Series.
3. Применение функции к каждому элементу в DataFrame:
df['Повышенная заработная_плата'] = df['Заработная плата' ].apply(lambda
х: х * 1.1С) # Увеличение зарплаты на 10%
print("\nDataFrame с применением функции для увеличения зарплаты:\n", df)
Используем метод apply () для применения функции к каждому элементу
столбца < Заработная плата > в DataFrame df. Также используем лямбда-функ-
цию, которая увеличивает значение зарплаты на 10 % (х * 1.1С). Результат
сохраняем в новый столбец < Повышенная_заработная_плата >. Выводим обнов-
ленный DataFrame на экран, чтобы увидеть изменения.
О а и. сомамае a patova < Sari**
• pd.Sarla»((14, 20, 34, ♦*, 341. naw* Числа*)
priatf"АлСоадамкм SarieatVn*, atMbara.sariaa)
prl«t(“V<ywa iMawwrw Sarlec: , na4»r|^irl<».»a(
pri*t(”Cp»Aw* ааачепм* Sarieti’» nwOcrt lerlei.aeaaf))
• 12. fVwewew* * <ад*шу weekly a OataFrwe
««(''Пмммпмаа.зареФотмаа.плата'] • Of {' Мработжаа лаата'].ар₽1>Г1аН*й «; ж * 1.14) в Умличата >арш«т«> на ЮТ
prl«t(*\*©»terra«a с прмиепенней fywqw л*а у*е*ич«*а аарпдвты-\n", <Н1
Tepoa'i (‘Мм»»*’, Хаикт-Петербург', 'Камма', *0ла*мост*с*),
‘Haceaexw*: |11920000, 3»»400, 1299400, 440000)
>
Рис. 10.26
На этом этапе мы успешно создали Series и применили функции к элемен-
там в DataFrame. Работа с Series позволяет легко хранить и манипулировать
одномерными данными, в то время как применение функций через метод
apply () предоставляет гибкость в обработке данных DataFrame. Эти операции
представляют собой важные аспекты анализа данных, которые позволяют
исследовать и модифицировать наборы данных эффективно. Теперь у нас
есть новые агрегированные значения для Series и обновленный DataFrame
с повышенными значениями заработной платы.
Слияние DataFrame
Объединим два DataFrame по общему столбцу. Слияние данных — распро-
страненная операция при работе с наборами данных, позволяющая комбини-
ровать информацию из разных источников в единую структуру.
1. Создание дополнительного DataFrame:
adoitional_data = {
'Город': ['Москва', 'Санкт-Петербург', 'Казань', 'Владивосток'],
’Население': (11920000, 5384000, 1253000, 600000]
df2 = pd.DataFrame(additional_data)
Создаем словарь additicnal data, который содержит информацию о насе-
лении для разных городов. Используем pd.DataFrame() для создания нового
DataFrame dfz на основе этого словаря, в котором будут два столбца: < Город >
и 'Население'.
2. Слияние DataFrame:
merged df = pd.merge(df, af2, on='Город', how='left')
Применяем функцию pd.mergeO, чтобы объединить оригинальный
DataFrame df и новый DataFrame df2. Указываем оп=>Город>, чтобы выполнить
слияние по столбцу 'Город', который присутствует в обоих DataFrame. Ис-
пользуем параметр how= >left >, чтобы сохранить все данные из df, даже если
для некоторых городов нет соответствующих данных в df2. Так мы получим
полный набор данных из первого DataFrame с добавлением информации о на-
селении, где это возможно.
3. Вывод объединенного DataFrame:
print ("\г.0бъединенный DataFrame:\n", merged df)
С помощью функции print () выводим содержимое объединенного
DataFrame merged df на экран, чтобы просмотреть результат операции слия-
ния. Мы увидим, как объединились данные из двух наборов и какие допол-
нительные данные добавлены.
Мы успешно объединили два DataFrame — оригинальный и дополнитель-
ный — по общему столбцу < Город >. Слияние данных позволяет эффективно
комбинировать информацию из различных источников, делая набор данных
более полным и информативным. Эго важная операция в анализе данных,
которая позволяет создавать обширные и всеобъемлющие структуры, гото-
вые для дальнейшего анализа и визуализации. Теперь у нас есть объединен-
ный DataFrame, который включает информацию о населении городов наряду
с данными о сотрудниках на основе их местоположения.
• 14 тебяяцы
piv©t_t«bl» • df.pivot_t4bIc(v«k*et*°34p«6oTM»a м»»»’, 1nde**'Город э «ggfunc)
printСХгЛиют-тобви**» п» Ср»дне* »*рп*вт»:\п’, pivot_toble)
Пноот• т*6я«м* по средне* м*«моте1
lopaOotnaa мота
•ород
Екатеринбург бТМб.б
Н0«М 7S4M.*
Санкт-Петербург 62М0.6
• 15. бмэуаляэаим tiniei
{pert Mtplotlib.pyplot as pit
plt.flfue«(figtize»(l>, 5))
pit. Mat (df | 'bo зреет*], bin»-4, color»' тку blue ', olpM^.7)
Рис. 10.27
Нивот-таблицы
Создадим пивот-таблицу из нашего DataFrame. Пивот-таблицы — это
мощный способ суммирования и анализа данных, позволяющий увидеть вза-
имосвязи и обобщения по определенным категориям.
1 . Создание пивот-таблицы:
pivot taole = df.pivot_table(values='Заработная плата', index='Город',
aggfunc='mear.')
Используем метод pivot tablet) на нашем DataFrame df. Указываем
values= Заработная плата >, чтобы определить, что хотим агрегировать именно
эти данные. Задаем index=>Город> для группировки записей по уникальным
значениям из столбца < Город >. Используем aggfunc= >mean >, чтобы вычислить
среднее значение заработной платы для каждого города. Результат сохраняем
в переменной pivot_table, которая будет содержать средние заработные пла-
ты, сгруппированные по городам.
2 Вывод пивот-таблицы:
print("\пПивот-Табл. по средней зарплате:\n", pivot_table)
С помощью функции print () выводим созданную пивот-таблицу па эк-
ран. Так мы увидим обобщенные данные, которые показывают, какая сред-
няя заработная плата у сотрудников в разных городах.
Мы успешно создали пивот-таблицу, которая показывает среднюю за-
рплату сотрудников по городам. Пивот-таблицы — это мощный инструмент
для анализа, поскольку они позволяют легко группировать и агрегировать
данные, что делает их удобными для визуализации и интерпретации инфор-
мации. Создание пивот-таблиц — важный шаг в исследовательском анализе
данных, который позволяет получать полезные выводы на основе собранной
информации. Теперь у нас есть сводка но средней заработной плате сотруд-
ников в различных городах, что может быть полезно для наблюдений и даль-
нейшего анализа.
ф । 14. Лям' «&4т*в
pivot_teble - Заработай мете', 1л4еж>'Город', aggfwK »'«мал *)
рг1лг(*\гОмао1-1а4яиц« по cpejneA мрпла<с1\м*. pivot,tabla}
Город
f сатаржбург в ’ооо. <в
Мослаа >5йОв.«
Само-Петербург 82ем.«
Ф 11. Вязуами « >>я данмас
(•port Matplotlib.pyplot а» pit
pit.figura^f10, 5))
plt.hist(df('OospacT*J, blfii-4, eolor^'skyfclMe", alpha«0.7)
pit.titlc('Гистограмма аоарастм сотрудничав')
pit.xlabelf'OaspPCT')
pit .ylobtl(‘K«*<MwcTwe сотру^мкоа*)
pit.grid(a«i»»*y‘)
plt.showf)
a 10. SaarftM»» работ» С РаМм
p<lftt("XftPa6oia с библиотекой Pandas ааоермим!')
в Установка ОмОмотеки aclklt-laam
Iplp install «clkit-laam
Мпортяруаш пеоОкодмм*
[apart ливру at лр
iaport pandas at pd
1eport aatplot11b.pyplot at pit
froe skleam.aodei_selectlon iaport traln_test_split
free skltarn.preprocessing laport Stondardicaler
froe skiearn.linear aodel ! apart lodistirtearession
Рис. 10.28
Визуализация данных
Визуализируем данные, используя библиотеку Matplotlib. Визуализация
помогает лучше понять распределение и характеристики данных, а также вы-
явить тенденции и взаимосвязи.
1. Импорт библиотеки для визуализации:
import matplotlib.pyplot as pit
Импортируем библиотеку matplotlib.pyplot под псевдонимом pit, кото-
рая предоставляет функции для создания различных типов графиков и диа-
грамм.
2. Создание гистограммы:
pit.figure(figsize= (10, 5))
pit.hist(df['Возраст'], bins=4, color='skyblue', alpha=0.7)
Используем plt.figure(figsize=(lC, 5)) для настройки размера графика.
Применяем pit.hist () для создания гистограммы на основе данных из
столбца < Возраст > DataFrame df. Задаем параметр bins=4, чтобы разбить
возраст на 4 диапазона (группы). Указываем цвет color= >skyblue > и прозрач-
ность alpha=0.7, чтобы стилизовать гистограмму.
3. Настройка заголовка и меток:
plc.title('Гистограмма возрастсв сотрудников')
pit.xlabel('Возраст')
pit.ylabel('Количество сотрудников')
plt.grid(axis='y')
Задаем заголовок графика с помощью plt.title(). Используем pit.
xlabel () и plt.ylabei() для определения названий осей X и Y соответствен-
но. Вызываем pit.grid (axis= >у >), чтобы добавить сетку на оси Y для улучше-
ния читаемости графика.
4. Отображение графика:
plt.showO
Вызываем pit. show (), чтобы отобразить созданный график на экране. Это
позволяет нам визуально увидеть распределение возрастов сотрудников.
5. Завершение работы с Pandas:
print ("\п.Работа с библиотекой Pandas завершена!")
Используем print () для вывода сообщения о том, что работа с библиоте-
кой Pandas завершена. Это служит подтверждением завершения всех мероп-
риятий по анализу и обработке данных.
о » IS. Лйшвт
Import »«tplot Mb.pyplot ♦» pit
pll.hi4t(dfr 'Возрмт’ |, blM-4. color-'»*y bl ue, «lphe-4.7)
Т»<тсгр»им во>*асто« cvrpy*M«o«')
pH - (' *eyp»C »’)
р1«.у1»Ьв1('к<м«*»ктм eoipy*нисв»’)
pH ')
p)t.sftov{)
2.00
150
12»
100
075
050
025
ООО
Гистограмма eoipacroe сотрудников
28 0 2B.5 29.0 29.5 30 0 30.5
Работа c ftw&mer*ieok РллЗл» ммуютм»!
Рис. 10.29
На этом этапе мы успешно визуализировали распределение возрас-
тов сотрудников с помощью гистограммы. Визуализация данных помогает
лучше понимать распределение и взаимосвязи в данных, а также делиться
результатами анализа в более наглядной форме. Завершение работы с биб-
лиотекой Pandas завершает цикл обработки и анализа данных, который мы
проводили на протяжении всех предыдущих этапов.
Машинное обучение и искусственный интеллект
Машинное обучение — это область искусственного интеллекта, направлен-
ная на разработку алгоритмов, способных обучаться на основе данных и де-
лать предсказания или принимать решения. Python, благодаря наличию биб-
лиотеки scikit-learn, предоставляет исследователям и разработчикам мощный
инструментарий для реализации различных задач машинного обучения.
Библиотека scikit-learn: от предобработки данных
до оценки моделей
Scikit-learn — одна из наиболее популярных библиотек для машинного обу-
чения в Python, которая предоставляет реализацию множества алгоритмов
и методов для классификации, регрессии, кластеризации и других задач.
Основные этапы работы с scikit-learn
Создадим небольшой собственный набор данных и продемонстрируем
основные методы и функции библиотеки scikit-learn на этом датасете. Нам
необходим набор данных о студентах, где есть различные признаки, такие
как возраст, время учебы, оценка по экзамену, и будем предсказывать, сдадут
ли они экзамен.
Установка библиотеки scikit-learn и импорт необходимых библиотек
Сначала мы установим библиотеку scikit-learn, а затем импортируем все
необходимые библиотеки для работы сданными и моделями машинного обу-
чения. Этот этап важен, так как он подготавливает среду для дальнейшего
анализа и обработки данных.
1. Установка библиотеки scikit -learn:
!pip install scikit-learn
Используем команду Ipip install scikit-learn, которая устанавлива-
ет библиотеку scikit-learn в текущую среду выполнения (например, Google
Colab). Эта библиотека предоставляет инструменты для машинного обуче-
ния, включая модели, функции для оценки и обработки данных.
2. Импорт необходимых библиогек:
import numpy as пр
import pandas as pa
import matplotlib.pyplct as pit
Импортируем библиогеку Numpy под псевдонимом пр, которую будем
использовать для работы с массивами и математическими операциями. Им-
портируем библиотеку Pandas под псевдонимом pd, которая предоставляет
удобные структуры данных (такие как DataFrame) для обработки и анализа
данных. Импортируем библиотеку matplotlib.pyplot под псевдонимом pit
для визуализации данных и построения графиков.
3. Импортируем модули из scikit-learn:
from sklearn.modei_selection import train test split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegressicn
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracyscore, classification_report,
ccnfusion_matnx
from sklearn.model_selection import cross_val_score
Импортируем:
• train_test_split для разделения набора данных на обучающую и тес-
товую выборки;
• StandardScaler для стандартизации данных перед обучением моделей;
• LogisticRegressj-on, DecisionTreeClassifier и RandomForestClassifier
для создания и обучения различных моделей машинного обучения;
• функции accuracy_score, classification_report и confusion_matrix для
оценки производительности моделей;
• cross val score для выполнения кросс-валидации, что позволит оце-
нить надежность моделей.
ф • Установка scikit 1ео>
Ipip Install scikit learn
гм* *ортеру«м нервioa<«<< бнблнотехм
Upert пмру as np
lapcrt pandas as pd
lapprt •etploilib.pyplot os plc
free Bkleem.eQdel.xiectipfi lapgirt troln_te»t_spHt
free sklcam.prepr«eiiing iaport itandardiealer
Hnear_aod«l I«port legist!(Regression
from sklearn.cr«« Inpert Dec IsiontreoClassifier
free sklearn. enseMle Leport ftandeWorostClastlf ier
free sklearn. Meries Laport accurocyscore, elassifleation_repwt, <onfusit>n_Mtri*
free sklearn.nodel_selection inport cross_val_score
•" Ruqulгемпt already satisfied: scikit-learn In /usr/local/ILb/python).l2/di*t-packag«s (1.4.1)
RaqulrMMt already satisfied: пмру»1.1».» In /uar/local/lib/pythonl.12/dist-patkeges (fmn selkit-learn) (2.0.1)
Rcquireaent already satisfied: scipy>-1.0.0 in /wflocal/Lib/pythonj.Wdist-packages (free scikit-learn) (1.16.3)
RequireMnt already satisfied: }obllb>-l-2.® in /usr/local/lib/python3.12/dist packages (free scikit-learn) (1.5.3)
Requirement already satisfied: threadpool<tl>-3.1.® tn /wsr/lota1/1ib/p/thonj.12/dist-packages (fro* scikit-learn) (3.*.®)
Sata - {
‘Bosрост': [i«, I*, 2®, 21, 22, 23, 10, 24, 1®, 2®J,
Врем_уме<ш'| (5, 3» 6, 7, •» 2, 4» 9, 3, 5),
*QMH«a_no_n«MMwy*; (3, 2, 5, 4, 5, 1, 2, 3, 1, 4),
’C***_mjm*': [•, ®, 1, 1, 1, ®, •» 1, *, 1] 0 1- слал, • - м сдал
а Препвразуем a DatafraM
df - pd.Dotafгам(data)
а Просмотр набора м-м
prlMt(*He6op ла>макс\л*, df)
9 2. каждеаенне л» их на прнамам и цеаеоу* мрем—у<а
* • df ((’Возраст’, *Врем_уче4и', ,Сее>«1_по_><мнс»)г,|)
у • df[ Caar_»ss«M»«']
Мы успешно установили библиотеку scikit -learn и импортировали все не-
обходимые библиотеки для работы с данными и моделями машинного обу-
чения. Это важный шаг, обеспечивающий основу для дальнейшего анализа
данных и построения моделей в процессе работы с набором данных.
Создание собственного набора данных
Создадим собственный набор данных для использования в дальнейшем
анализе и обучении моделей. Набор данных будет состоять из различных
признаков, таких как возраст, время учебы и оценка по экзамену, а также це-
левой переменной, указывающей, сдал ли студент экзамен.
1. Определение данных:
data = {
'Возраст': [18, 19, 20, 21, 22, 23, 18, 24, 19, 20],
'Время_учебы': [5, 3, 6, 7, 8, 2, 4, 9, 3, 5],
'Оценка_по_экзамену': [3, 2, 5, 4, 5, 1, 2, 5, 3, 4],
'Сдал_экзамен/: [С, 0, 1, 1, 1, 0, 0, 1, 0, 1] # 1 - сдал, С - не
сдал
Создаем словарь data, который будет содержать списки значений для раз-
личных признаков и целевой переменной, включающие 'Возраст', 'Вре:ля_
учебы', 'Оценка_по_экзамену'. Целевая переменная <Сдал_экзамен> указывает,
справился ли студент с экзамепо.м (1 — сдал, 0 — не сдал).
2. Преобразование словаря в DataFrame:
df = pd.DataFrame(data)
Применяем функцию pd.DataFrame () из библиотеки Pandas для преоб-
разования словаря data в DataFrame df. DataFrame представляет собой двух-
мерную таблицу, в которой строки соответствуют наблюдениям (студенты),
а столбцы — признакам (возраст, время учебы и т. д.).
3. Просмотр набора данных:
print("Набор данных:\n", df)
Используем функцию print () для вывода содержимого DataFrame на эк-
ран. Это позволяет просмотреть созданный набор данных и убедиться, что
структура и значения признаков сформированы правильно.
Мы успешно создали собственный набор данных с использованием сло-
варя Python, который был преобразован в DataFrame с помощью библиотеки
Pandas. Это важный шат для подготовки данных перед их анализом и машин-
ным обучением. Теперь у нас есть структурированный набор данных, кото-
рый мы можем использовать для обучения моделей и оценки их производи-
тельности.
• 2. ₽♦**»•«•<*• "• прутняки и «KAfwyw перемг^уч
X - df[ **о>рвст' , «би ', *О1И4«4_П0_»к>«м*иу*] ]
у - 4Г['Сдм_зк1*мем']
1. Ле*и—е дан»—; wa <4yii»yi и v«ci«*y* ««борки
X_tr«l«, y_tr«i«, /.test • у, tett_tiie»4.2, r«mto*_st«te»42)
• 4. Стандартизация лиигг
teal»*' • StaMardScalerO
X_*rai«i_Mal*d • »««l»r.fit_tran»fprw(X_tratn)
X tatl tcalad - »e*l»r.tran*f<w-*(x_t»tt)
Рис. 1031
Разделение данных на признаки и целевую переменную
Разделим наш набор данных на признаки (независимые переменные) и це-
левую (зависимую) переменную. Это важный шаг перед обучением моделей
машинного обучения, так как модели работают с признаками для предсказа-
ния целевой переменной.
1. Определение признаков;
X = df[['Возраст', 'Время учебы', 'Оценка_по экзамену']]
Создаем переменную X, которая будет содержать признаки, используе-
мые для предсказания. Используем синтаксис DataFrame df [ l< ... >] ], чтобы
выбрать несколько столбцов из нашего DataFrame df, что позволяет указать
конкретные признаки: 'Возраст', 'Ьремя_учебы' и 'Оценка_пс_экзамену'. Пе-
ременная X теперь содержит данные, относящиеся к выбранным признакам
для всех студентов.
2. Определение целевой переменной:
у = df['Сдал экзамен']
Создаем переменную у, содержащую целевую переменную (результат),
которую мы попытаемся предсказать. Используем синтаксис DataFrame
df [<... >], чтобы выбрать один столбец, содержащий целевую переменную
'Сдал экзамен'. Переменная у теперь хранит информации» о том, сдал ли эк-
замен каждый студент (1 — сдал, 0 — не сдал).
Мы успешно разделили наш DataFrame на признаки (X) и целевую пере-
менную (у). Признаки будут использоваться для обучения моделей машин-
ного обучения, а целевая переменная будет представлять собой результат,
который мы хотим спрогнозировать. Подготовка данных — важная часть
процесса машинного обучения, поскольку она влияет на качество и точность
получаемых моделей.
А J. «* «аиицос м« п^«мы « ж
И df j ’ Вр*ий у-ч«4ш', ’Оцгниа ,М_»«.1ам«му1|)
у - 4<(*С*м_э<ммен')
3. Деление ли mi на о&угчмцу* н тестеву» аа>Сорк»
X.truin, /.train, y.trst - trnln.test.splltfX, у, teit.slie-O.Z, r*Mba_stnte-42)
• 4. Сталдарткмчм лаялл
scalar • SttAdardScalarf)
X.trein.scnlrd • sceler ,f it_tr*<vsfore(X_tr*in)
X_t«»t_scala4 • sc«l«r.tr«nsf9r»(x_t«»t>
5. ijpyiirime мменй
Догнстнмасяал раерассм
Ia<_<aodel legist UHagrett 1с«ц)
l«C.«odel.fit(M_train_scaled, /.train)
• Jbrpaao pew***
tr««_wd«l - twUlMiTrwtleisifi«r{)
tree_«odel.fit(X_train_scaled, /.train)
а Случай^й лес
foeast aodal - fUndo*rorrs<<l*s*lfl«r<)
forest.node 1.1 it (X.tr«Ln.scaled, /.train)
for nodal. near in zip(nodali, nodal.nanas)S
y_pred - aMel.predict(X_rcst_scaled)
accuracy • accurecy.scor'e(y.t«it> y_^r«d)
prlntff 4«<««жт» дла naae s <accuracy•. 20')
Рис. 10.32
Деление данных на обучающую и тестовую выборки
Разделим наш набор данных на обучающую и тестовую выборки. Это не-
обходимо для того, чтобы обучить модель на одной части данных и оценить
ее производительность на другой, что позволяет избежать переобучения
и проверить обобщающую способность модели.
1. Деление данных на обучающую и тестовую выборки:
X train, X test, у train, у test = train test split(X, у, test size=0.2,
random state=42)
Используем функцию train_test_split() из библиотеки sklearn.model
selection для разделения данных. Передаем ей аргументы:
• X: матрица признаков;
* у: целевая переменная;
• test size=O .2: указываем, чго 20 % данных должно бьг1 ь отведено для
тестовой выборки, а оставшиеся 80 % — для обучающей выборки;
* random state=42: фиксируем значение random state для обеспечения
воспроизводимости результатов, так как функции разделяют данные
случайным образом.
Результат деления записывается в переменные X train, X test, у train,
и y_test.
Стандартизация данных
После разделения данных мы стандартизируем их, чтобы улучшить про-
изводительность и стабильность машинного обучения.
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test scaled = scaler.transform(X test)
Создаем экземпляр StandardScaler, который используется для стандар-
тизации данных, чтобы они имели пулевое среднее значение и единичную
дисперсию. Вызываем метод fit transform() на обучающей выборке X tra^n
для вычисления параметров (среднее и стандартное отклонение) и транс-
формации данных. X_train_scaled — это стандартизированная обучающая
выборка. Вызываем метод transform () на тестовой выборке X test, используя
параметры, вычисленные на обучающей выборке. X test scaled — это стан-
дартизированная тестовая выборка.
Мы успешно разделили данные на обучающую и тестовую выборки, а так-
же стандартизировали их. Наличие этих выборок позволяет обучать модель
на одной части данных и затем оценивать ее производительность на отде-
льных данных, что важно для машинного обучения. Стандартизация помо-
гает улучшить качество модели, обеспечивая совместимость и стабильность
признаков.
X • df ([ ’Возраст ’, 'ерсяа_умебм'. 'Оченм^по^акааиену" J ]
у • df('Сдал.жаамен')
О Деление даммм на • тестеву» мбср«а
Х_сг»1д, y_train, ?_<•** * у, te*t_»iz*««i z, randoa_*tate-42)
4. Стандартивациа даиав»
s-caler • Standard$caler()
X_eral*_j<aked Maler.fit_tran»*ore(X train)
K_tr»t_»caled »cal«r.tran»forept_t**t)|
• $. Обучение моделей
тичвскав регрессе
log_ao4el - Lofiieic«*fmilon )
lop oodel .flt(X_traie_Kaled, y_tral«)
Дерево
trec_eedel • Deci tierlreeClaisif ier( )
tree_»tx*el .71t(X_tr>i»_e<*led1 y_trale)
a лес
fore*t oodel - ftaMaafarestCleaaif!•*•()
f. f lt(X_traii»_»cal«1, y_train)
4. F^cKrrenepoaamie и оцемга моделей
•odeli • [lopeodel, tree_eod«l. foreiteodel}
•ode 1 naeei • ['Доевстмесхав регресс»»', 'Jfepeao речений', 'Случат»» лес’)
for aodel, паев in zlp(«edeli, aodel_nae«*>s
j_pred - eodel.predict (X_te*t_K*le4J
accvracy accveacy. »<ore(y_teit, y_prad)
printff'Точное?* дав {лада}: (ассчгасу; .2f }'}
print(f'Отчет классификации дли (imm \nfclaulfIcat 1оп_гврогс(у_ге»«, y_pred)]*)
print(f Матрица иута*вцд« дга паве5 :\r>iconfo»ioeweatri>ryw_te*t, У_рге4)}\п')
a 7. Кросс-аалндма*" дм с«туча1Ь«ого леса
cv_M«r»» - cro»»_v»l_»<ore(fore*t_eodel. X, у, cv-i)
Рис. 10.33
Обучение моделей
Создадим и обучим три различных модели машинного обучения на под-
готовленных данных. Каждый из этих методов имеет свои особенности и мо-
жет использоваться для решения задач классификации.
1. Обучение модели логистической регрессии:
log model = Logistidegression ()
log_model.fit(X_train_scaled, y_train)
Создаем экземпляр класса LogisticRegression, который будет представ-
лять модель логистической регрессии. Вызываем метод fit () на стандартизи-
рованной обучающей выборке X_train_scaled и целевой переменной у train
для обучения модели. Модель логистической регрессии будет использовать
признаки для оценки вероятности того, что студент сдал экзамен (1 — сдал,
О — не сдал).
2. Обучение модели дерева решений:
tree_model = DecisionTreeClassifier()
tree model.fit(X train_scaled, y_train)
Создаем экземпляр класса DecisionTreeClassifier, который будет пред-
ставлять модель дерева решений. Вызываем метод fit () на стандартизиро-
ванной обучающей выборке и целевой переменной аналогично предыдущему
шагу. Модель дерева решений будет строить дерево, принимающее решения
на основе значений признаков для классификации студентов по результатам
экзамена.
3. Обучение модели случайного леса:
forest model = RandomForestClassifier()
forest_moael.fit(X crain_scaled, y_train)
Создаем экземпляр класса RandomForestClassifier, который будет пред-
ставлять модель случайного леса (ансамбль деревьев решений). Вызываем
метод fit() на стандартизированной обучающей выборке и целевой пере-
менной. Модель случайного леса будет обучаться, создавая множество дере-
вьев решений и комбинируя их прогнозы для получения более точного ре-
зультата.
Мы успешно обучили три различных модели машинного обучения: ло-
гистическую регрессию, дерево решений и случайный лес. Каждая из них
использует обучающие данные для изучения связи между признаками и це-
левой переменной, что позволит нам проводить про] нозирование на тесто-
вом наборе данных. Эта часть процесса машинного обучения — ключевой
этап, так как именно здесь модели учатся извлекать полезные зависимости
из данных.
X df( 'Время, *Ом«ям«.П9.МММ*яу*))
у • df[ 'Слл"_»«э*м«' ]
Э. Л<-«—* **"•*< “• обучив» к тестмув мборкк
«.train, X_t«»t, y.train, y.t«»t • tr*ln.t«»t.«pllt(X, у, t«»t_»lieM. 2, r»n<k>e_»tatr-*J)
• 4. С»*п**рти5*ци« д>ч а»-
scalar - Stan4ar45cal«rt)
X_traln_i<al«d scalar.fit.transfere(X_train)
x.tatt.Malad - *ealar.tranifara(X_teit)
• . Г^«гм0<>мроаан»е • s^<an«a мдгвгк
«ode В - [l«t_«9da], trar aodel, f<M-ot ]
odal.naar* ('Яагжигаескм parpacewa', 'Дарам f >mi nJ*, 'Случаем* *«']
for Mdel, пам in }1р(амй1«, eodpl.naee»)s
• Mdrl.prediet(X_ta«_scal«4)
accuracy accuracy_scor«(y_t«st, у ,pr«d
print(f’Точност» для .паве 1 (accuracy .20')
prlat(f Отчет классвржацмм для (мве ln{classifi<*tion_r«port(y_twt, y_pr«d).,‘)
prlAt(f'Матрица луг«ак«« для (лаве}i\A(c<Mfusien_aatrlx(y_test, у_р<«4) -л’)
Рис. 10.34
Прогнозирование и оценка моделей
Теперь используем обученные модели для прогнозирования результатов
на тестовой выборке и проведем оценку их производительности. Мы будем
смотреть на точность каждой модели, а также выводить отчет о классифика-
ции и матрицу путаницы.
1. Сбор моделей и их имен:
models = [log_mcdel, tree_moael, forest_model]
model names = ['Логистическая регрессия', 'Дерево решений', 'Случайный
лес' ]
Создаем список models, содержащий все обученные модели: log model,
tree_model и forestjnodel. Создаем список model_names, в котором хранятся
соответствующие имена моделей, чтобы использовать их позже для вывода
результатов.
2. Цикл прогнозирования и оценки:
for model, name in zip(mcdels, model names):
y_pred = model.preoict(X_test_scaled)
accuracy = accuracy_score(y_test, y_pred)
print(f'Точность для [name): {accuracy:.2f}’)
print(f'Отчет классификации для {name}:\n{classification
report(y rest, y_pred)}')
print(f'Матрица путаницы для {name}:\n{confusion_matrix(y_test,
y^pred)}\n')
Используем цикл for с zip() для одновременной итерации по спискам
models и model_naraes.
• model: текущая модель, которую мы будем оценивать;
• name: имя текущей модели.
Для каждой модели:
* Прогнозирование:
python y_pred = model.predict(X_test_scaled)
Используем метод predict () на стандартизированной тестовой выборке
X_test_scaled, чтобы получить прогнозируемые значения y_prcd (результаты
на тестовой выборке).
* Оценка точности:
python accuracy = accuracy_sccre(y_test, y_pred)
Вычисляем точность модели с помощью функции accuracy score(), срав-
нивая прогнозируемые значения y pred с фактическими значениями y test.
• Вывод результатов:
python print(fzТочность для {name}: {accuracy:.2f}')
Выводим точность текущей модели с форматированием до двух знаков
после запятой.
* Отчет о классификации:
python print(f'0T46T классификации для {name}:\n{classification
report(y_test, y_pred)}')
Генерируем отчет классификации с помощью функции classification-
reportO, который включает метрики, такие как точность, полнота
и F1 мера.
• Матрица путаницы:
python print(f'Матрица путаницы для {name}:\n{confusion_matrix(у_
test, y_pred)}\n')
Выводим матрицу путаницы, используя confusionjnatrix (), чтобы пока-
зать количество истинно положительных, ложноположительных, истинно
отрицательных и ложноотрицательных результатов для каждой модели.
Мы использовали обученные модели для прогнозирования результатов
на тестовой выборке и провели всестороннюю оценку их производительнос-
ти. Полученные данные о точности, отчеты о классификации и матрицы пу-
таницы позволяют лучше понять, как модели работают на реальных данных
и каким образом они могут быть улучшены в будущем.
с 6. Лрогеимроеанае х оценка моден**
odels • [lop_«od*l, tree_aod*l, forest_eo4el]
aod«l_n*aes • ('Логастамескм регресс***, °Д*р**с ртотм*', 'Случаем* **«']
for »odel, naaa* in zip(*od*ls, apdel.n****);
y_pr»d - odel.predlct(X_t*st_scal«4)
accuracy “ aceuracy_s«ore(y_t*»t, y_pr*d>
prlMff‘Точности для {nsee[i {accuracy,,H)’)
prlnt(f’Отчет «ласс>*4жешм лял naee )i\n[clas»l*icatlen_reporc(y_t«t, у_ргМ)Г)
prlot(f’Матраца путане») для (пме)]\й confusion_eatrix(y-testJ УвРг*^))'п’)
Ту ост» для Логнстммескав регресспв: 1.М
Отчет классафм.ммя дм Логястнмскда регрессаа:
precision recall fl-score support
• l.M l.M l.M 2
accuracy l.M 2
aero avg l.M l.M l.M 2
*ight*d avg l.M l.M l.M 2
латртща гтутавпцм дм Догвствчесва* perpeccaa:
[[2]]
1счюст> для Дерев» ртшмй: 1.М
Отчет классяфмам* для Дерево ре**тм
precision recall fl-»core support
• l.M IM l.M 2
accuracy l.M 2
aero avg l.M l.M l.M 2
eightcd avg l.M l.M l.M 2
Матрмца путаема» дм Дерево pewevwd;
l(i]J
трчмете для СоучаАмМ мс: 1.М
Отчет млаесярмсаяем для Случай^ *eei
precision recall ft**cer« support
Рис. 10.35
Натрин еугамаеи дм СаучаДчА мс
№П
/м»г,Г1ма)ЛШру***а>Л2/41*'-рм*ас»^1Н»маУмтг(«(<.<1а'г1*1««т1м.ру>а*>< MeeMMlag! a «Ugle UM1 м» *м«4 !• 'y.t'**' »***' е«г tM <м*ч»1«* м*»1« та к*м
MrMngi .«(
/мг/1ас<1/11Ь/ргСМа>.12/е1»1.ра<Ъасет/1к1(«г«/мсг<с1/_£1а1»1*1<е11м рттаа»! WaHAmlag: Л slxple 1а0«1 vei foand la ’y.trw" aad 'y_prW. ear th* eorfaslan aatri* to hew
arwlng*-Mrw<
/MrTlocal/lia/nrtMoj.U/elst pocMpes/skleareZartrlcsZ.cUsslficatlsn.pycMyi v*er«amiapi » slept* la*«l нм <««M la ‘y^tru*' aap 'у_ргм'. ear th* caafwian aatrU to h*v«
мт lag*
i i 1
Рис. 10.36
(РН
/udr/locol/llWpythMS.U/dllt frOckagts/ihlaam/vtrlcaJ^eUaslficatloo.pyiM?: tXcrwwinf: A labal uai fawrf ta y.true" and 'yjpni . For the «onfwiltn aatrlz t* bare the correct «b^t, vm
fuer/local/llWfrytlwI.U/dlat-piK^n/iAltom/aaCrUty.cUaalflcatloa.pyidni * М4.1* JaOai «•> f««>M ta 'y.trve' and ’y_prod'. for t«M> corf Mian oatrU to haua the correct UMpe.
anrtlng» .—mf
/w»r/lQcal?llb/pythaa>.U?d:(t>|»ckaf)r>/ckleern/artricc/.cUccitHatta».ry:H7: irtwwr»l»<i A t|ii(la lake! wa> faond to ’/„true' and 'y^prad . For the confmton oatrU to kava the correct «Аара, -с»
amlaft.narof
• >. tpo«< eiacAtwa ем crynfeoa ae<a
cw_»core* • <ra»_«aX_*oare, farwat^mdal, X, Jr, c«*5J
priaeff'(ft»-— та., ar та ay« . par-ear мма» > •*•*»•« cayuatnoro aecai ay.oeae(rv_««ere»}: >f)')
О * * ha«Th*e>o«*n eriyaerereo
faatwe^iaportancec • rare*»^«deL.feetore i^ertaneea^
♦retiree . X.raltac^c
Indite» • r».arc*ertrt#»ter«_iay#rt»ncr»)( 1 t-l]
Рис. 10.37
Сообщение о предупреждении и матрица путаницы, которую мы получи-
ли, указывают на то, что в данных, которые мы использовали для оценки мо-
дели, присутствовало только одно значение как в фактических, так и в пред-
сказанных данных.
Metwna WOmnw1 А*- С*Г опо* М<:
IUI)
SM'7lMab'lLWpytMAj.t2/dlH-H<M*rWrtl*arA/wtrU*J,_clM»iflco«l«A.tyi««?n U>c»***l*CI А *!**!« U*«. »е» »i*M 1" 'y.trw' <М 'yjrt4'. Г»г ЧМ «*|г{к to Me* t*O torr«« iMc. WM
woroiact.ooroi.
• a. >»iya«уе^аптооо
feature (одо-Ламе* • forvst лМс1, feature, lapertaAci-.
features > l.<alw»>
indieei > i».arf>ort(Гаосиге_lnyertao<»»)(:: в]
rit.«i«oro(ftetioo>{ia, «»
frit.tltl«(*a«пюег». аразпосо» *ta *w«n> oryeataora Mto*)
plt.harf'o«t«K.(*<dpc{t] , fooWo_U»*rt*a<»c| jnauotj, •ll^w’coMor')
plt.rtf<Ot('an<a(X n* array faabrut J 8«fr|c«« , r*iati«n>4
frlt.aMot l, х.амо.{1]|
frlt.ylaMH
•It.tMoO
Рис. 10.38
Кросс-валидация для случайного леса
На этом этапе мы проводим кросс-валидацию для модели случайного ле-
са. Кросс-валидация помогает оценить обобщающую способность модели,
используя разные подмножества данных для обучения и тестирования. Это
позволяет нам понять, насколько надежна модель на различных выборках
данных.
1. Импорт необходимых библиотек (если не импортированы):
from sklearn,model selection import cross val score
import numpy as np
Убедимся, что импортировали функцию cross val_score из sklearn.
model selection и библиотеку numpy для вычислений.
2. Проведение кросс-валидации:
cv_scores = cross j7al_score(forestjnodel, X, у, cv=5)
Используем функцию crcss val score () для выполнения кросс-валидации
на модели случайного леса (forestjnodel). Аргументы для этой функции:
• forestjnodel — обученная модель случайного леса, которую мы хотим
оценить;
• X — матрица признаков, используемая для обучения и тестирования;
• у — целевая переменная, которую мы пытаемся предсказать;
• cv=5 указывает на количество фолдов (разбиений) для кросс-валида-
ции. В данном случае данные будут разбиты на 5 частей и модель будет
обучена и протестирована 5 раз на различных подмножествах данных.
3. Вывод средней точности:
print(f'Средняя точность при кросс-валидации модели случайного леса:
{np.mean(cv_scores):.2f}')
Используем функцию np.mean() из библиотеки numpy, чтобы вычислить
среднее значение точности (cv scores), полученной на каждом фолде. Затем
выводим среднюю точность кросс-валидации на экран с помощью print ()
и форматируем результат до двух знаков после запятой.
Мы успешно использовали кросс-валидацию для оценки модели случай-
ного леса. Используя разные подмножества данных, можно более полно и на-
дежно оценить производительность модели. Средняя точность, полученная
в результате кросс-валидации, дает более реалистичное представление о том,
как модель будет работать на новых невидимых данных, чем проверка только
на тестовой выборке.
Визуализация результатов
Проведем визуализацию важности признаков, использованных в модели
случайного леса. Важность признаков позволяет понять, какие факторы ока-
зывают наибольшее влияние на предсказания модели. Это полезно для ин-
терпретации результатов и понимания модели.
1. Получение важности признаков:
feature_importances = forest_mcdel.feature_importances
Используем атрибут feature_importances модели случайного леса (forest
model), чтобы получить оценку важности каждого признака. Она показывает,
насколько каждый признак способствовал принятию решений.
2. Определение названий признаков:
features = X.columns
Сохраняем названия признаков из DataFrame X в переменную features,
чтобы затем использовать их для отображения на графике.
3. Сортировка признаков по важности:
indices = r.p.argsort(feature_importances) [::-1]
Используем функцию np.argsort() из библиотеки numpy для получения
индексов признаков, отсортированных по убыванию их важности. [::-1]
указывает на то, что сортировка должна быть выполнена в обратном порядке
(от большего к меньшему).
4. Создание графика:
plt.figure(figsize=(lC, 6))
pit.title("Важность признаков для модели случайного леса")
plt.oar(range(X.shape[1]), feature importances[indices], align="center")
Инициализируем новый рисунок с заданными размерами (Юхб дюймов).
Задаем заголовок графика. Строим столбчатую диаграмму, где по оси х рас-
полагаются индексы признаков, а по оси у — их важность, отсортированная
с использованием полученных ранее индексов.
5. Настройка осей и отображение результатов:
plt.xticks(range(X.shape[l]), np.array(features)[indices], rotation=45)
plt.xlim([-1, X.shape[l]])
plt.ylabei('Важность')
plt.showO
Устанавливаем метки для оси х, используя названия признаков в порядке
их важности, с поворотом на 45 градусов для лучшей читаемости. Устанавли-
ваем пределы по оси х от -1 до количества признаков для правильного отоб-
ражения всех значений. Задаем название для оси у как < Важность >. Вызываем
функцию pit.show (), которая отображает созданный график.
Мы визуализировали важность признаков, использованных в модели слу-
чайного леса. Этот график помогает понять, какие признаки имеют наиболь-
шее влияние на предсказания модели, что может быть полезно для дальней-
шего анализа данных, предварительной обработки, оптимизации признаков
и интерпретации результатов. Визуализация результатов — важная часть
процесса анализа данных и машинного обучения.
Q *8. Визуммзвфи р ультстав
fe*?ur«_ieport«r<ei - far*tt_ao0el.f«rturt_Uport«K«t_
fcatires • X.colons
indicts • np.argiort(f*etvre_lMport«nc«s)[:;-1]
pit,figure^*icsite«<16, 6)pj
plt-titlel’BamocT» признаков для модели случайного леса'')
pit. b*r(ra-<e(X. shaped ], featwre_iap<x-t*oc«[iMlces], align-'centef)
pltuctickaCrangctX.shapetl]), np.array feature* J indices], rotation-45)
plt.xll*((-l, X.shaped)])
pit,уlabel(•Важноеть•)
pit.зЪомч)
Рис. 1039
Выводы
В этой главе мы рассмотрели основные библиотеки Python, которые исполь-
зую для научных вычислений, анализа данных и машинного обучения. NumPy
и Pandas предоставляют инструменты для эффективной работы с данными,
a scikit-learn и Matplotlib/Seaborn — для построения моделей и визуализации
результатов.
Основные выводы:
NumPy — фундамент для научных вычислений, который реализует высо-
копроизводительных массивов и математических функций.
Pandas дает мощные инструменты для анализа и манипуляции табличны-
ми данными.
Scikit-learn — одна из наиболее популярных библиотек для машинного
обучения, которая реализует алгоритмы классификации, регрессии и клас-
теризации.
Визуализация данных с помощью Matplotlib и Seaborn позволяет выяв-
лять закономерности и представлять результаты.
Рекомендации по дальнейшему изучению
Для углубленного изучения темы рекомендуем ознакомиться со следующими
ресурсами:
• TensorFlow/PyTorch для реализации задач глубокого обучения.
* Jupyter Notebook для интерактивного анализа данных.
* Raggle для решения реальных задач и участия в соревнованиях по ма-
шинному обучению.
Заключение
Python, благодаря наличию мощных библиотек, предоставляет исследова-
телям и разработчикам инструменты для решения широкого спектра задач,
связанных с научными вычислениями, анализом данных и машинным обу-
чением. Освоение этих инструментов позволяет значительно повысить эф
фективность работы и достигать более высоких результатов в своей деятель-
ности.
Глава 11
Путь Python-разработчика
Будучи языком с практически неограниченным потенциалом, Python пред-
ставляет собой платформу для бесконечного профессионального роста. В за-
ключительной главе мы рассмотрим основные направления дальнейшего
развития в экосистеме Python, а также методы эффективного участия в open-
source проектах. А также обсудим философию Python и ее влияние на про-
цесс обучения и профессиональной деятельности.
Пути дальнейшего обучения
Ключевой аспект профессионального роста в области Python — непрерывное
обучение и освоение новых технологий и методологий. Ниже представлены
основные направления, которые могут быть рекомендованы для углубления
знаний и расширения компетенций.
Углубление в специализации
1. Data Science.
Python — один из ведущих языков в области Data Science, который пре-
доставляет широкий спектр инструментов для анализа данных и машинного
обучения. Для углубленного изучения этой специализации рекомендуем сле-
дующие ресурсы:
• Курсы. Python for Data Science and Machine Learning Bootcamp (Udemy).
Этот курс предоставляет всестороннее введение в Data Science с ис-
пользованием Python.
• Практика. Участие в соревнованиях на платформе Kaggle позволяет
не только применить полученные знания на практике, но и получить
ценный опыт работы с реальными данными.
2. Веб-разработка.
Python предлагает множество фреймворков для разработки веб-приложе-
ний, среди которых выделяются Django и Flask. Для дальнейшего изучения
веб-разработки можно рассмотреть следующие направления:
* Django REST Framework. Этот фреймворк предоставляет мощные
инструменты для создания RESTful API, что делает его идеальным для
разработки серверной части веб-приложений.
• Асинхронные фреймворки. Для повышения производительности веб-
приложений можно рассмотреть использование асинхронных фрейм-
ворков, таких как FastAPI и Quart.
3. Автоматизация и DevOps.
Python — мощный инструмент для автоматизации и управления инфра-
структурой. Для освоения этих направлений можно рекомендовать следую-
щие ресурсы:
• Ansible. Этот инструмент позволяет автоматизировать управление
конфигурациями и развертыванием приложений.
• CI/CD. Для автоматизации процессов непрерывной интеграции и до-
ставки можно использовать такие платформы, как GitHub Actions
и GitLab CI.
Книги для вдохновения
Для углубленного изучения Python и смежных областей рекомендуем следу-
ющие книги:
• «Чистый Python. Тонкости программирования для профи» Дэна
Бейдера предоставляет ценные инсайты и советы по написанию чис-
того и эффективного кода.
• В «Python. Книга рецептов» Дэвида Бизли собраны практические
примеры и решения для различных задач, что делает ее незаменимым
ресурсом для разработчиков.
* «Грокаем алгоритмы» Адитьи Бхаргавы представляет собой фунда-
ментальное введение в алгоритмы, что особенно полезно для подго-
товки к собеседованиям.
Сообщества
Активное участие в профессиональных сообществах — важный аспект
профессионального развития. Для Python-разработчиков доступны как рус-
скоязычные, так и международные сообщества.
Русскоязычные сообщества Python Russian Community в Telegram дает
возможность обмениваться опытом и знаниями с другими разработчиками
на русском языке. Также стоит обратить внимание на митапы и конферен-
ции, такие как PyCon Russia и MoscowPython
Международные сообщества: платформа Real Python предлагает обшир-
ную библиотеку статей и туториалов, а РуРА занимается развитием экосис-
темы пакетов для Python.
Участие в open-source проектах
Участие в open-source проектах дает уникальную возможность для профес-
сионального роста, позволяя не только приобрести опыт работы с реаль-
ным кодом, но и внести вклад в проекты, которыми пользуются миллионы
людей.
Почему это важно?
Участие в open -source проектах имеет ряд значимых преимуществ:
• Получение опыта работы с реальным кодом. Работа над реальными
проектами позволяет развить навыки решения сложных задач и улуч-
шить понимание архитектуры программного обеспечения.
* Участие в проектах с широким сообществом. Работа над популярными
проектами позволяет установить контакты с ведущими специалиста-
ми в своей области.
• Возможность стать частью истории. Примеры таких проектов, как attrs,
демонстрируют, что вклад в open-source сможет оставить значительный
след в истории программирования.
Как начать?
Можно воспользоваться следующими рекомендациями:
1. Найдите подходящий проект.
Существует множество платформ, которые позволяют найти проекты,
подходящие для новичков. Среди них можно выделить:
• GitHub Explore позволяет искать проекты по различным тегам, вклю-
чая good first-issue, что упрощает процесс поиска задач, подходящих
для начинающих разработчиков.
• Up For Grabs специализируется на проектах, которые открыты для
участия новичков и предоставляют четкие инструкции по внесению
вклада.
2. Внесите первый вклад.
Найдя подходящий проект, приступайте к внесению первого вклада. Вот
несколько рекомендаций:
• Неправые опечатку в документации. Это простой, но значимый вклад,
который может улучшить качество проекта.
• Решите простую задачу из Issues. Выберите задачу с тегом good-first-
issue и следуйте инструкциям в описании задачи.
3. Создайте Pull Request (PR).
После внесения изменений необходимо создать Pull Request (PR), который
позволит внести ваш код в основной репозиторий проекта. 11ри создании PR
важно соблюдать следующие рекомендации:
• Описание изменений должно быть ясным и кратким, с указанием про-
блемы, которую вы решаете, и способа ее решения.
• Убедитесь, что ваш код соответствует стилю, используемому в проекте,
и прошел все необходимые тесты.
• Если ваш вклад включает изменения в документацию, убедитесь, что
они также включены в PR.
Заключение
Python — это не просто язык программирования, а целая экосистема, кото-
рая предоставляет бесконечные возможности для профессионального роста.
Независимо от того, решите ли вы углубиться в Data Science, веб-разработку,
автоматизацию или DevOps, участие в open-source проектах и следование фи-
лософии Python позволят вам стать более компетентным и востребованным
специалистом.
Помните, что каждый ваш шаг на этом пути — это вклад в общее развитие
сообщества Python. Не бойтесь задавать вопросы, делиться своими знаниями
и стремиться к постоянному совершенствованию.
Список источников
1. Anaconda, Inc. Anaconda [Электронный ресурс]. — Режим доступа: https://
www.anaconda.com/ (дата обращения: 27.04.2024).
2. JetBrains. PyCharm [Электронный ресурс]. — Режим доступа: https://www.
jetbrains.com/pycharm (дата обращения: 27.04.2024).
3. Jupyter Project. Jupyter [Электронный ресурс]. — Режим доступа: https://jupyter.
org/ (дата обращения: 27.04.2024).
4. Google. Google Colaboratory [Электронный ресурс]. — Режим доступа: https://
colab.research.google.com (дата обращения- 27.04.2024).
5. Федоров Д. Ю. Программирование на python : учебное пособие для ву-
зов / Д. Ю. Федоров — 6-е изд., перераб. и доп. — Москва : Юрайт, 2025. —
187 с. — (Высшее образование). — ISBN 978-5-534-19666-5. — Текст : элект-
ронный И Образовательная платформа Юрайт [сайт]. — URL: https://urait.ru/
bcode/556864 (дата обращения: 30.09.2025).
6. Федоров Д. Ю. Программирование на python : учебник для среднего
профессионального образования / Д. Ю. Федоров. — 6-е изд., перераб.
и доп — Москва : Юрайт, 2025. — 187 с. — (Профессиональное образова-
ние). — ISBN 978-5-534-19654-2. — Текст : электронный И Образовательная
платформа Юрайт [сайт]. — URL: https://urait.ru/bcode/563564 (дата обраще-
ния: 30.09.2025).
7. Martindale N., Smith J., Linville L. Supporting Greater Interactivity’ in the IPython
Visualization Ecosystem. — Oak Ridge National Laboratory (ORNL), Oak Ridge,
TN (United States), 2024.
8. Gorelick M., OzsvaJd I. High Performance Python: Practical Performant
Programming for Humans. — O’Reilly Media, Inc., 2025.
9. Jupyter Project. Установка классической версии Jupyter Notebook [Электрон-
ный ресурс]. — Режим доступа: https://jupyter.readthedocs.io/en/latest/install/
notebook-classic.html (дата обращения: 17.04.2024).
10. JetBrains. PyCharm [Электронный ресурс]. — Режим доступа: https://www.
jetbrains.com/pycharm/ (дата обращения: 20.04.2024).
11. Основные сведения о Python [Электронный ресурс]. — Режим доступа: https://
basic-pylhon.readthedocs.io/en/latest/what_python.html — Дата обращения:
27.04.2024).
12. Синтаксис языка программирования [Электронный ресурс]. — Режим досту-
па: https://example.com/syntax (дата обращения: 15.06.2023).
13. BDFL [Электронный ресурс]. — Режим доступа: https://realpylhon.com/ref7
glossary/bdfl/ (дата обращения: 15.06.2023).
14. Как редактировать код на Python [Электронный ресурс]. — Режим досту-
па: https://wiki.pylhon.org/moin/HowToLditPylhonCode (дата обращения:
15.06.2023).
15. Кабалин А. П. Использование pylhon при разработке мобильных приложений
для android //Вестник науки. — 2025. — Т. 1 — № 5 (86). — С. 596-607.
16. Шипило Д. Е. и др. Язык программирования Python. — 2024.
17. Чоу Э. Python для сетевых инженеров. Автоматизация сети, программирова-
ние и DevOps: Решение реальных задач. — Питер, 2023.
18. Яворски М., Зиаде Т. Pylhon. Лучшие практики и инструменты. — Питер,
2023.
19. Симакин К. С., Акчурин А. Р., Михалев А. Г. Сравнение языков программиро-
вания C++ и Pylhon для работы с машинным обучением И Вестник Пензенс-
кого государственного университета. — 2025. — № 1 (49). — С 118-120.
20. Олимпиев Н. В. Разработка методики тестирования интерпретаторов языка
Python для веб-приложений // E-Scio. — 2022. — .№ 3 (66). — С. 471-477.
21. Таршхоева Ж. Т. Язык программирования Python. Библиотеки Python // Мо-
лодой ученый. — 2021. — № 5. — С. 20-21.
22. Любанович В. Простой Pylhon. Современный стиль программирования.
2-е изд. — Питер, 2023.
23. Модуль codecs в Python [Электронный ресурс]. — Режим доступа: https://docs-
python.ru/standart-library/modul-codecs-pylhon/ (дата обращения: 15.06.2023).
24. Модуль math в Pylhon [Электронный ресурс]. — Режим доступа: https://docs.
python.org/3/library/math.html (дата обращения: 15.06.2023).
25. Модуль ге в Pylhon [Электронный ресурс]. — Режим доступа: https://docs.
python.org/3/library/re.html»module-re (дата обращения: 15.06.2023).
26. Matplotlib: библиотека для визуализации данных [Электронный ресурс]. —
Режим доступа: https://maiplotlib.org/ (дата обращения: 15.06.2023).
27. Pandas: библиотека для анализа данных [Электронный ресурс]. — Режим до-
ступа: https://pandas.pydata.org/ (дата обращения: 15.06.2023).
28. SciPy: библиотека для научных вычислений [Электронный ресурс]. — Режим
доступа: https://scipy.org/ (дата обращения: 15.06.2023).
29. PyPI: Python Package Index [Электронный ресурс]. — Режим доступа: https://
pypi.org/ (дата обращения: 15.06.2023).
30. Pip: установка и управление пакетами Python [Электронный ресурс]. — Ре-
жим доступа: https://pypi.org/project/pip/ (дата обращения; 15.06.2023).
31. Документация Python [Электронный ресурс]. — Режим доступа: https://docs.
python.org/З/ (дата обращения: 15.06.2023).
32. Документация Python: Модули [Электронный ресурс]. — Режим доступа:
https://docs.python.Org/3/tutorial/modules.html (дата обращения: 15.06.2023).
33. РЕР 20 — Густая философия Python [Электронный ресурс]. — Режим доступа:
https://peps.python.org/pep-0020/ (дата обращения: 15.06.2023).
34. Условные операторы в Python [Электронный ресурс]. — Режим досту-
па: https://realpython.com/python-conditional-slatcments/ (дата обращения:
15.06.2023).
35. Бейдер Д. Чистый Python. Тонкости программирования для профи. — Питер,
2022.
36. Получение пользовательского ввода в Python с помощью input [Электрон-
ный ресурс]. — Режим доступа: https://pythonru.com/osnovy/poluchenie-
polzovatelskogo-woda-v-python-s-input (дата обращения: 15.06.2023).
37. Озерова Г. II. Основы программирования на языке Python в примерах и зада
чах. — 2022.
38. Карякин М., Ватульян К., Мнухин Р. Технологии программирования и ком-
пьютерный практикум на языке Python. — Litres, 2022.
39. Берман К. Основы Python для Data Science. — Питер, 2023.
40. Мусин Д. Самоучитель Python И Выпуск 0.2. URL: https://docplayer.
ru/25829012-Samouchitel-python-vypusk-0-2-dmitriymusin. html (дата обраще
ния: 01.02. 2021).— 2017.
41. Python.ru. Функция range в Python [Электронный ресурс]. — Режим досту
па: https://pythonru.com/osnovy/funkcija-range-v-python (дага обращения:
27.04.2024).
42. Python.ru. Python для Data Science: Встроенные функции и методы
Python [Электронный ресурс]. — Режим доступа: https://pylhonru.com/
osnovy/3-python-dlja-data-science-vstroennye-funkcii-i-metody-python (дата об-
ращения; 27.04.2024).
43. Stack Overflow на русском. Отличие format от f [Электронный ресурс]. — Ре-
жим доступа: https://ru.stackoverflow.eom/questions/l 168937/%D0%9E%Dl%82
%D0%BB%D0%B8%D 1. %87%D0%B8%D0%B5-format-%D0%BE%D 1 %82-f (дата
обращения: 27.04.2024).
44. Документация по языку Python. Функция enumerate [Электронный ре-
сурс]. — Режим доступа: https://docs-python.ru/tutorial/vstroennye-funktsii-
interpretatora-python/funktsija-enumerate/ (дата обращения: 27.04.2024).
45. Python.ru. Функция zip для начинающих [Электронный ресурс]. — Режим до-
ступа: https://pythonru.com/uroki/funkcija-zip-dlja-nachinajushhih (дата обра-
щения: 27.04.2024).
46. Senjun.ru. Уроки Python [Электронный ресурс]. — Режим доступа: https://
senjun.ru/courses/python/chapters/python_chapter_0190/ (дата обращения:
27.04.2024).
47. Code Basics. Основы Python. URL: https://code-basics.com/ru/languages/python/
lessons/basic (дата обращения: 27.10.2023).
48. Петренко И. Приоритетность и ассоциативность операторов для начинающих.
URL; https://pythonru.com/uroki/29-prioritetnost-i-associativnost-operatorov-
dlja-nachmajushhih (дата обращения; 27.10.2023).
49. Летяев Л. Операторы присваивания. URL: https://letpy.com/handbook/
assignment-operators/ (дата обращения: 27.10.2023).
50. Code Basics. Конкатенация строк. URL: https://code-basics.com/ru/languages/
python/lessons/string-concatenation (дата обращения: 27.10.2023).
51. Python Software Foundation. Ввод-вывод. L[RL: https://docs.python.Org/3/ tutorial/
inputoutput.html (дата обращения: 27.10.2023).
52. Real Python. Введение в переменные Python. URL: https://realpython.com/
python-variables/ (дата обращения: 27.10.2023).
53. Real Python. Основные структуры данных в Python. LTRL: https://realpython.
com/learning-paths/basic-python-data-structures/ (дата обращения: 27.10.2023).
54. Python Software Foundation. Встроенные функции Python. URL: https://docs.
python.org/3/library/functions.html (дата обращения: 27.10.2023).
55. Exercism. Сравнения в Python. URL: https://exercism.org/tracks/python/concepts/
comparisons (дата обращения: 27.10.2023).
56. Real Python. Оператор in в Python. URL: https://realpython.com/python-in-
operalor/ (дата обращения: 27.10.2023).
57. CodeChef.ПроблемаPYTHCL39A. URL: https://www.codcchef.com/learn/course/
python/LTCPY08/problems/PYTHCI.39A (дата обращения. 27.10.2023).
58. Real Python. Оператор and в Python. URL: https://realpython.com/python-and-
operator/ (дата обращения: 27.10.2023).
59. Stack Overflow. Приоритет логических операторов (порядок операций для net,
and, or). URL: https://stackoverflow.com/questions/16679272/prioriiy-precedence-
of-the-logical-operators-order-of-operations-for-not-an (дата обращения;
27.10.2023).
60. Rosetta Code. Короткое замыкание (Short-circuit evaluation). URL: https://
rosettacode.org/wiki/Short-circuit_evaluation (дата обращения: 27.10.2023).
61. Zid C. et al. List Comprehension Versus for Loops Performance in Real Python
Projects: Should we Care? //2024 IEEE International Conference on Software
Analysis, Evolution and Reengineering (SANER). — IEEE, 2024. — C. 592-601.
62. Python Wiki. Цикл for, URL: https://wiki.python.org/moin/ForLoop (дата обра-
щения: 27.10.2023).
63. Документация Python. Стандартные функции. URL: https://docs.python.org/2/
library/funciions.html (дата обращения: 27.10.2023).
64. CodeHS. Операторы break и continue в Python. URL: https://codehs.com/tutorial/
rachel/break-and-continue-in-python (дата обращения: 27.10.2023).
65. Code Basics. Цикл while в Python. URL: https://code-basics.com/languages/
python/lessons/while (дата обращения: 27.10.2023).
66. Real Pylhon. Строки в Python. URL: https://realpython.com/python-strings/ (дата
обращения: 27.10.2023).
67. Документация Pylhon. Метод str.replace (). URL: https://docs-pylhon.ru/
tutoriaJ/operatsii-tekstovymi-strokami-str-python/metod-str-replace/ (дата обра-
щения: 27.10.2023).
68. Programiz. Метод str. find () в Pylhon. URL: https://www.programiz.com/python-
programming/methods/string/find (дата обращения: 27.10.2023).
69. Programiz. Метод str.count О в Python. URL: https://www.programiz.com/
pylhon-programining/methods/string/count (дата обращения; 27.10.2023).
70. Мэтиз Э. Изучаем Python: программирование игр, визуализация данных, веб-
приложения. 3-е изд. — Питер, 2023.
71. Learn Python. Срезы строк в Pylhon. URL: https://learnpython.com/blog/string-
slicing-in-pylhon/ (дата обращения: 27.10.2023).
72. FreeCodeCamp. Как выделить подстроку из строки в Pylhon. URL: https://www.
freecodecamp.org/news/how-to-substring-a-string-in-python/ (дата обращения:
27.10.2023).
73. Real Pylhon. Функция len () в Pylhon. URL: https://realpylhon.com/len-pylhon
function/ (дата обращения: 27.10.2023).
74. Seniuk Y. Pylhon dictionaries //Ukrainian and Foreign Science: Yesterday, Today,
Tomorrow. — 2021. — C. 99.
75. Документация по языку Pylhon. Метод dict.pop [Электронный ресурс]. — Ре-
жим доступа: https://docs-python.ru/tutorial/operatsii-slovarjami-diet-python/
metod-dict-рор/ (дата обращения: 27.04.2024).
76. Документация по языку Python. Метод list.clear [.Электронный ресурс]. — Ре-
жим доступа: https://docs-python.ru/tutorial/operatsii-izmenjaemymi-posledo-
vatelnostjaini-list-python/metod-list-clear/ (дата обращения: 27.04.2024).
77. Документация Python. Метод diet.keys () в Pylhon. URL; https://docs-pyi.hon.
ru/tutorial/operatsii-slovarjami- dict-python/metod- diet-keys/ (дата обращения:
27.10.2023).
78. Dumka P., Dumka R., Mishra D. R. Numerical methods using Pylhon (for scientists
and engineers). — Blue Rose Publishers, 2022.
79. Yarlagadda R. Т., Surya L., Patel D. M. Python for Beginners //Python for beginners,
REDSHINE Publications (2021), hitp://redshine. co. in/product/9798741059081. —
2021.
80. Hetland M. L., Nelli F. Lists and Tuples //Beginning Python: From Novice to Profes-
sional. — Berkeley', CA : Apress, 2024. — C. 25-45.
81. Харрисон M. Как устроен Python. Гид для разработчиков, программистов
и интересующихся. — Питер, 2022.
82. Озерова Г. П. Основы программирования на языке Python в примерах и зада-
чах. — 2022.
83. Бурнашев Р. А. и др. Анализ данных на языке программирования Python: Биб-
лиотека Pandas. — 2022.
84. Не X., Wang Z., Zhan S. Design and implementation of interactive image
measurement software based on Tkinter and PIL library //Proceedings of the
4th International Conference on Computer, Artificial Intelligence and Control
Engineering. — 2025. — C. 564-568.
85. Menguito H. D. D. et al. Employing Python Programming to Synthesize Digital
Audio with Pulse Code Modulation //International Conference on Intelligent
Computing & Optimization. — Cham : Springer Nature Switzerland, 2023. —
C.203-211.
86. Митчелл P. Скрапинг веб-сайтов с помощью Python. — Litres, 2022.
87. Гурбансахедов M. Ч., Дурбаева Ф. Д., Атаев Э. Python программирование и ООП:
углубленное изучение //Символ науки. — 2024. — № 2-2-2. — С. 31-32.
88. Саммерфильд М. Python на практике. Создание качественных программ с ис-
пользованием параллелизма, библиотек и паттернов. — Litres, 2022.
89. Чернышев С. Принципы, паттерны и методологии разработки программного
обеспечения: учебное пособие для вузов. — Litres, 2021.
90. Xanthidis D., Manolas C., Alhousary T. Database Programming with Python //
Handbook of Computer Programming with Python. — Chapman and Hall/CRC,
2022. — C. 273-317.
91. Gupta P., Bagchi A. Introduction to pandas //Essentials of python for artificial
intelligence and machine learning. — Cham : Springer Nature Switzerland, 2024. —
C. 161-196.
92. Савинчева А. С., Ференец А. А. Автоматизация чтения связанных данных
из реляционных и нереляционных баз данных в контексте использова-
ния стандарта JPA //Электронные библиотеки. — 2024. — Т. 27. — №. 4. —
С. 656-678.
93. Dhanagari М. R MongoDB and data consistency: Bridging the gap between
performance and reliability' //Journal of Computer Science and Technology
Studies. — 2024. — T. 6. — №. 2. — C. 183-198.
94. Martindale N., Smith J., Linville L. Supporting Greater Interactivity in the IPython
Visualization Ecosystem. — Oak Ridge National Laboratory (ORNL), Oak Ridge,
TN (United States), 2024.
95. Waskom M. L. Seaborn: statistical data visualization //Journal of open source
software. — 2021. — T. 6. — № 60. — C. 3021.
96. Gupta P, Bagchi A. Introduction to NumPy //Essentials of Python for Artificial
Intelligence and Machine Learning. — Cham : Springer Nature Switzerland, 2024. —
C. 127-159.
97. Gupta P, Bagchi A. Introduction to pandas //Essentials of python for artificial
intelligence and machine learning. — Cham : Springer Nature Switzerland, 2024. —
C. 161-196.
КНИГИ ЛУЧШИХ
W
РОССИЙСКИХ авторов
ПО ПРОГРАММИРОВАНИЮ
I
I
5
РОССИЙСКИЙ
КОМПЬЮТЕРНЫЙ
БЕСТСЕЛЛЕР
$
Васильев А.Н.
В ПРИМЕРАХ
И ЗАДАЧАХ
г ПРИМЕРАХ
И ЗАДАЧАХ
Основные сведения
о синтаксисе
и концепции языка
От простых объектно-
ориентированных
программ
до многопоточного
программирования
Примеры и задачи для
самостоятельного
изучения
Для студентов
и самостоятельного
изучения
Васильев АН.
ПРОГРАММИРОВАНИЕ
НА
Васильев А.Н.
ДЛЯ НАЧИНАЮЩИХ
УНИКАЛЬНЫЕ
МЕТОДИКИ
ТЫСЯЧИ
УСПЕШНЫХ
УЧЕНИКОВ
ПРИМЕРЫ
И ПОЛЕЗНЫЕ
СОВЕТЫ
В КАЖДОЙ ГЛАВЕ
Все права защищены Книга или любая ее часть не может быть
скопирована, воспроизведена в электронной или механической форме
ь виде фотокопии, записи в память ЭВМ репродукции или каким-либо
иным способом, а также использована в любой информационной системе
без получения разрешения от издателя. Копирование, воспроизведение
и иное использование книги или ее части без согласия издателя
является незаконным и влечет уголовную административную
и гражданскую ответственность.
Производственно-практическое издание
РОССИЙСКИЙ компьютерный бестселлер
Камалова Юлия Борисовна
ПРОГРАММИРОВАНИЕ НА PYTHON С НУЛЯ
Главный редактор Р. Фасхутдинов
Руководитель направления В Обручев
О1ветсгвенный редактор/? Салихова
Научный редактор А. Алексеев
Литературный редактор Н. Домнина
Младший редактор М Назаренко
Художественный редактор В. Братина
Компьютерная верстка Е Матусовская
Корректоры Е Ерошкина, Л Макарова
Страна происхождения: Российская Федерация
Шыгарушы ел: Ресей Федерациясы
ООО «Издательство «Эксмо
123308. Россия, г. Москва, ул, Зорге, д. 1. стр. 1, эт. 20, кэб. 2013. Тел. 8 (495)411 -68-86.
Home page www.eksmo ru E-mail: info@eksmo.ru
Ондруил. -Издательство «Эксмо» ЖШК,
123308, Ресей, Мэскеу каласы, Зорге кешво. 1 -уй. 1-курылыс, 20 кабат, 2013-каб.
Тел. 8 (495) 411-68-86 Home раде wwweksmo.ru E-mail: info@eksmo ги.
Тауар белпа: -Эксмо-
Интериет-магазин www.boo4c24.ru
Интернет-магазин: www.book24.kz
Интернет-дукен www.book24.kz
Импортер в Республику Казахстан ТОО «РДЦ-Алматы».
Казахстан Реслубликасына импорттаушы -РДЦ-Алматы ЖШС.
Дистрибьютор и представитель по приему претензий на продукцию
в Республике Казахстан; ТОО «РДЦ-Алматы»
ТОО РДЦ Алматы. Алматы, ул Домбровского 3«а«. литер Б, офис 1.
Дистрибьютор жене Казахстан Республикасында ен1мге шагымдар
кабылдэу жемндел ©юл: «РДЦ-Алматы» ЖШС
Алматы Х-. Домбровский кэш , 3 «а», литер Б, офис 1.
Тел.: 8 (727) 251 59-90^91/92. E-mail: RDC-Almaty@ek$mo.kz
Сведения о подтверждении сосиветствия издания согласно законидательсп^ РФ
о техническом регулировании можно получить на сайте Издательства «Эксмо»;
www.eksrno.ru/certification
Техникалых реттеу туралы РФ зацнамэсына сай басылымныцсайкесппн растау
гурапы мал<меттерД1 мыма адрес бойынша алуга болады http://eksmo.ru/certificaboo/
Произведено в Российской Федерации
Ресей Федерациясында онд)р1лген
Сертификаттауга жатпайды
Да гаизг о говления/Подписано в печать 03 04 2026 Формат 70x100 7„
Печа1ьофсе1нэя. Усл. нем л. 36,3
Тираж экз Заказ
Москва. ООО «Торговый Дом «Эксмо
Адрес 123308, г Москва, ул, Зорге, д 1. строение 1
Телефон +7(495)411-50-74. E-mail: receplion@eksmn-sale.ru
По вопросам приобрегения книг «Эксмо» зарубежными оптовыми
покупателями обращаться в отдел зарубежных продаж ТД «Эксмо»
E-mail: international@eksmo-sale.ru
International Sales. International wholesale customers should contact
Foreign Sales Department of Trading House «Eksmo-- for their orders
internaticnal@eksmo-sale ru
По вопросам заказа книг корпоративным клиентам, в том числе в специальном
оформлении, обращаться по тел : +7 (495) 411-68-59, доб 2151
E-mail borodkin.da@eksmo.ru
Оптовая торговля бумажно-беловыми
и канцелярскими товарами для школы и офиса «Канц-Эксмо»:
Компания «Канц-Эксмо» 142702, Московская обл.. Ленинский р-н, г. Видное-2,
Белокаменное ш. д. 1, а/я 5. Тел./факс: +7 (495) 745-28-87 (многоканальный).
e-mail kanc@eKsmo-saie.ru, сайт: www.kanc-eksmo.ru
Филиал «Торгов -го Дома «Эксмо» в Нижнем Новгороде
Адрес: 603094, г. Нижний Ноыород, улица Карпинского, д 29, бизнес-парк «Грин Плаза»
Телефон:+7(831)216-15-91 (92 93,94). E-mail: reception@eksmonn.ru
Филиал ООО «Издательство «Эксмо» в г. Санкт-Петербурге
Адрес. 192029, г. Санкт-Петербург, пр. Обуховской обороны, д 84. лит. «Е»
Телефон: +7 (812) 365-46-03 /04 E-mail: server@szko ru
Филиал ООО «Издательство «Эксмо» в г. Екатеринбурге
Адрес: 62^024, г. Екатеринбург ул Новинская, д. 2щ
Телефон: +7 (343; 272-72-01 (02/03/04/05/06/( 8)
Филиал ООО «Издательство «Эксмо» в г. Самаре
Адрес 443052, г Самара, пр-т Кирова, д. 75/1, лит. «Е»
Телефон-+7(846)207-55-50 E-mail RL>C-samara@mail ru
Филиал ООО «Издательство «Эксмо» в г. Ростове-на-Дону
Адрес. 344023, i Ростов-на-Дону. ул. Страны Совеюв, 44А
Телефон: +7(863) 303-62- 'О E-mail: info@rnd.eksmo.ru
Филиал ООО«Издательство «Эксмо- в г. Новосибирске
Адрес: 630015, г Новосибирск Комбинатский пер., д 3
Телефон- +7(383) 289-91 -42 E-mail: eksmo-nsk@yandex.ru
Обособленное подразделение в г. Хабаровске
Факшческии адрес 680000, г Хабаровск, ул. Фрунзе, 22, оф 703
Почтовый адрес 680020, г. Хабаровск, А/Я 1006
Телефон: (4212) 9Ю-120, 910-211 E-mail- eksmo-khv@mail.ru
Республика Беларусь: ООО «ЭКСМО ACT Си энд Си»
Центр оптово-розничных продаж Cash&Carty в г Минске
Адрес: 220014, Республика Беларусь, г. Минск, проспект Жукова. 44. пом. 1 17, ТЦ -Outleto»
Телефон +375 17 251-40-23, «375 44 581-81-92
Режим работы- с 10 иО до 22 OG E-mail: exmoast@yandex.oy
Казахстан: «РДЦ Алматы»
Адрес 050039, г. Алматы, ул. Домбровского ЗА
Телефон- +7 (727) 251-58-12. 251-59-90 (91.92,99). E-mail: RDC-Almaty@eksmo kz
Полный ассортимент продукции ООО «Издательство «Эксмо» можно приобрести в книжных
магазинах «Чигай-город» и заказать в интернет-магазине www.chitai-gorod.ru
Телефон единой справочной службы: 8 (800) 444-8-444 Звонок по России бесплатный.
Интерне!-магазин ООО -Издагельство «Эксмо»
www.eksmo.ru
Розничная продажа книг с доставкой по всему миру.
Тел.: +7 (495) 745-89-14 Е mail: imarket@eksmo-sale ru
ЧИТАЙТЕ
И СЛУШАЙТЕ
В Литрес к
IH ЧИТАН
III ГОРОД
вжв
eksmo.ru
Официальный
интернет магазин
издательства «Эксмо»
Хпчешь стать
автором «Эксмо»?
ТЕ1РИТОРИЯ
КНИЖНЫЙ МАГАЗИН
Официальная франшиза
издательства «Эксмо»
& БОМБОРА
4SS ИЗДАТЕЛЬСТВО
БОМБОРА - лидер на рынке полезных и вдохновляющих книг.
Мы любим книги и создаем их, чтобы вы могли творить, открывать
мир, пробовать новое, расти. Быть счастливыми. Быть на волне.
0 Dombora.ru с bomborabooks О:ЬотЬога
ПРОГРАММИРОВАНИЕ НА PYTHON С НУЛЯ
Это подробное руководство по основам программирования на языке Python, начиная
с введения в язык и заканчивая применением Python в научной среде и разработке
программного обеспечения.
Что внутри?
• Основы языка: изучение интерактивной среды IPython,
Jupyter Notebook, Google Colab и Anaconda.
• Управляющие и синтаксические конструкции.
• Структуры данных: понимание строк, словарей, кортежей и списков.
Объектно-ориентированное программирование: инкапсуляция,
наследование, полиморфизм и паттерны проектирования.
• Работа с базами данных: подключение к БД, ORM, SQLAlchemy
и анализ данных с помощью Pandas.
Вы получите исчерпывающие знания обо всех аспектах языка и много
полезных примеров, которые помогут освоить теорию и применить ее
на практике, научитесь создавать эффективные решения, оптимизи-
ровать код и готовить почву для профессионального роста в области
Python-разработкиг
Об авторе
Юлия Камалове — преподаватель и инженер в сфере IT и анализа данных.
На кафедре информационных технологий Финансового университета при Правитель-
стве РФ обучает студентов Python, ML и управлению данными с использованием
PostgreSQL. Имеет опыт преподавания в ЦДО МГТУ им. Баумана и работы
в компаниях нефтегазовой отрасли ("Нефтемаш", Ижевский нефтяной научный
центр), где занималась разработкой и внедрением информационных систем.
Эта книга — уверенная отправная точка для формирования инженерного мышления,
а не набора приемов. Здесь последовательно выстраивается фундамент: от базового
синтаксиса и структур данных Python до принципов и практик, без которых не обходится
современная разработка и работа с данными. Вдумчивый читатель получает связный
профессиональный маршрут, который одинаково полезен и для прикладной разработки,
и как база для входа в самые быстрорастущие направления ИТ — Data Science,
машинное обучение и инструменты ИИ.
t БОМБОРА
ИЗДАТЕЛЬСТВО
Дмитрий Зубрецкий,
технический директор targetai
ISBN 978-5-04-214684-8
9 785042 146848 >
БОМБОРА — лидер на рынке полезных и вдохновляющих книг
Мы любим книги и создаем их. чтобы вы могли творить, открывать
мир, пробовать новое, расти. Быть счастливыми. Быть на волне.