Множества в Python пришли из математики, где над ними можно совершать такие операции как объединение и пересечение, а также находить разность и симметричную разность.
Рассмотрим два множества: красные яблоки и зелёные груши. При этом оба множества содержат жёлтые яблоки и груши:
set1 = {"Красные яблоки", "Жёлтые яблоки", "Жёлтые груши"}
set2 = {"Зелёные груши", "Жёлтые груши", "Жёлтые яблоки"}
Объединение двух множеств – это новое множество, которое содержит все элементы обоих множеств. В математике объединение двух множеств A и B обозначается как A ∪ B.
Для того, чтобы наглядно представить множества и отношения между ними, используем круги Эйлера. Каждый круг представляет одно множество, а область внутри него – его элементы. Перекрывающиеся области между кругами показывают элементы, которые являются общими для этих множеств.
В Python всё является объектом, поэтому функции могут принимать, и возвращать другие функции, а также одна функция может содержать другую. Всё вместе это лежит в основе таких понятий, как замыкание и декораторы, позволяющие расширять возможности функций.
Вложенная функция всегда имеет доступ к переменным, определенным в её внешней функции. И этот доступ – не просто временная передача значений, а постоянная ссылка на ячейки памяти, где эти значения хранятся.
Ключевой момент, который превращает этот механизм в замыкание, происходит, когда внешняя функция завершает свою работу. В обычной ситуации, когда функция заканчивает выполняться, все её локальные переменные уничтожаются. Однако это не происходит, если выполняются следующие ключевые условия:
- Внутренняя функция использует переменные внешней функции.
- Внешняя функция возвращает внутреннюю функцию.
В таком случае Python понимает, что вложенная функция всё ещё нуждается в переменных из внешней области, и эти переменные «замыкаются» вместе с вложенной функцией. Они не являются копией, а представляют собой прямую связь с исходными данными.
В большинстве реальных приложений недостаточно просто обрабатывать данные в оперативной памяти, так как часто требуется сохранять информацию между запусками программы или загружать ее из внешних источников. Для этого используется работа с файлами на диске.
По способу хранения информации все файлы делятся на текстовые и бинарные (двоичные).
Байты внутри текстового файла представляют символы (с учётом используемой кодировки), которые мы можем прочитать и увидеть на экране. Такие файлы удобны для хранения текстовой информации.
В бинарных файлах байты не соответствуют символам напрямую, а представляют собой различные структуры данных: машинные инструкции, пиксели изображений, аудиоданные и другие элементы, в зависимости от формата файла. Поэтому бинарные файлы не предназначены для непосредственного чтения человеком.
Когда мы пишем программы, важно не только то, что делает код, но и то, как он выглядит. Хорошо оформленный код легче читать, понимать, отлаживать и поддерживать. Для языка Python существует официальное руководство по стилю кода под названием PEP 8 (от англ. Python Enhancement Proposal – Предложение по улучшению Python).
PEP 8 представляет собой обширный документ, включающий множество рекомендаций по стилю и оформлению кода на Python. Однако, поскольку мы только начинаем изучение Python, мы рассмотрим только самые основы, такие как:
- Базовые правила отступов и форматирования.
- Советы по использованию пробелов и длин строк.
- Важность аккуратного комментирования и соблюдения регистра.
Логическими выражениями называют утверждения, которые могут быть оценены как истинные или ложные. Например, выражение «Идёт дождь» в зависимости от погоды будет истинным или ложным. Так и в Python результатом вычисления любого логического выражения всегда будет значение логического типа данных True или False.
Логические выражения в сочетании с ветвлением являются фундаментальным инструментом в программировании, позволяя выполнять различные действия в зависимости от того, выполняются ли определенные условия. С их помощью можно реализовать проверку пароля, фильтрацию данных или управление потоком выполнения программы.
Любой объект в Python обладает определенным логическим значением, которое можно получить с помощью встроенной функции bool() (от англ. boolean – булев (логический) тип данных).
Функция bool() возвращает True, если объект считается истинным, и False, если объект считается ложным.
К истинным значениям относятся любые непустые объекты и ненулевые числа:
print(bool("В саду распустились розы"))
# Вывод: True
print(bool({"Имя": "Копатыч", "Место жительства": "Долина Смешариков"}))
# Вывод: True
print(bool(256))
# Вывод: True
В Python, как и во многих других языках программирования, у каждой переменной есть своя область видимости, которая определяет, в какой части программы к ней можно получить доступ. То есть переменная, определенная в одном месте, может быть невидима в другом.
С областями видимости тесно связано понятие пространства имён. Оно представляет собой систему, которая связывает имена (например, переменных и функций) с соответствующими объектами в программе. Python использует иерархическую структуру пространств имен для управления областями видимости.
Для определения, где Python ищет имя переменной или другого объекта, используется правило LEGB. Это аббревиатура определяет порядок поиска имен. Python ищет имя, начиная с самой внутренней (локальной) области и двигаясь наружу. Если имя найдено, поиск прекращается. Если оно не найдено ни в одной из областей, возникает исключение NameError.
В Python функции являются объектами, поэтому их можно присваивать переменным, возвращать из других функций и передавать в качестве аргументов другим функциям.
И если функция делает хотя бы одно из двух:
- принимает одну или несколько других функций в качестве аргументов;
- возвращает функцию как результат своей работы.
То такая функция называется функцией высшего порядка.
Одной из таких функций является функция sorted(), с которой мы познакомились, когда говорили о сортировке списков. Ей можно передать функцию, которая будет применяться к каждому элементу итерируемого объекта перед сортировкой:
vegetables = ["Баклажан", "Щавель", "Тыква", "Сельдерей", "Спаржа"]
print(sorted(vegetables, key=len)) # Сортировка по длине строки
# Вывод: ['Тыква', 'Щавель', 'Спаржа', 'Баклажан', 'Сельдерей']
Поэтому функция sorted() является функцией высшего порядка. Кроме неё в Python представлены функции map() и filter().
Помимо обычных функций, которые мы создаём с помощью ключевого слова def, в Python существуют так называемые анонимные функции, которые не имеют имени и представляют собой небольшие однострочные функции. По-другому их называют лямбда-функциями (от англ. lambda functions) из-за их связи с лямбда-исчислением, разработанным американским логиком и математиком Алонзо Чёрчем в 1930-х годах.
В этой системе функция представляется в виде выражения, которое начинается с греческой буквы лямбда λ. Например, функция, которая удваивает число, в лямбда-исчислении записывается как λx * 2, где:
- λ – указывает на начало определения функции;
- x – аргумент функции;
- 2 * x – тело функции.
Многие языки программирования, включая Python или JavaScript, заимствовали эту концепцию для создания небольших одноразовых функций.
Формат JSON (от англ. JavaScript Object Notation – нотация объектов JavaScript) – это текстовый формат, который чаще всего используется для обмена данными в современных информационных системах.
JSON был создан как способ представления структур данных в JavaScript, но быстро стал популярным благодаря своей простоте, читаемости и лёгкой интеграции практически с любым языком программирования.
JSON оперирует двумя основными структурами, которые напрямую соответствуют основным коллекциям Python: объектами и массивами.
Объекты (англ. objects) представляют собой неупорядоченный набор пар «ключ: значение» и соответствуют словарям в Python.
При работе со строками довольно часто возникает необходимость найти нужное сочетание символов внутри строки или подсчитать, сколько раз оно встречается в этой строке. Также часто требуется убедиться в том, что строка соответствует нужному формату, например, состоит только из чисел или начинается с определённой строки.
Для поиска подстроки в строке Python предоставляет два основных метода: str.index() и str.find(). Оба метода предназначены для обнаружения первого вхождения указанной подстроки и возвращают индекс начала этого вхождения.
Ключевое различие между этими двумя методами заключается в их поведении, когда подстрока не найдена:
- метод
str.index() в такой ситуации вызовет исключение ValueError, что приведёт к прерыванию выполнения программы;
- метод
str.find() просто вернёт -1, и программа дальше продолжит работу.