Справочник по Python с примерами кода

Перевод статьи «The Python Code Example Handbook».

Лишь немногие языки программирования пользуются такой же всеобщей любовью, как Python. Детище голландского программиста Гвидо Ван Россума — Python мощный, простой в изучении и очень приятный в работе.

Благодаря своей популярности, видео- и письменные ресурсы, посвященные Python, легко доступны. Наш справочник по Python не претендует на звание полного и всеобъемлющего пособия. Но он познакомит вас со всеми темами, которые я считаю основами языка, с большим количеством примеров кода.

Я не рассматривал в этом руководстве объектно-ориентированное программирование, поскольку считаю, что это очень обширная тема, заслуживающая отдельного руководства.

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

Содержание

Предварительные требования

Чтобы освоить материал из этого справочника, вам не нужно знать никакой другой другой язык программирования. Но знание любого ЯП может помочь вам понять основы Python.

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

Установка Python на компьютер

Установка Python на компьютер — очень простой процесс. А если вы работаете в системе Linux, Python уже должен быть установлен.

Откройте окно терминала и выполните следующую команду:

python --version

Если Python установлен в вашей системе, то вы получите сообщение типа Python 3.10.4 (версия может отличаться).

Хотя в большинстве современных дистрибутивов Linux по умолчанию используется Python 3, некоторые старые дистрибутивы могут по-прежнему использовать по умолчанию Python 2.

Поэтому, если вышеупомянутая команда выводит версию Python 2, попробуйте выполнить следующую команду:

python3 --version

Я бы также посоветовал проверить наличие обновлений в вашем дистрибутиве Linux и установить все новые обновления для Python.

Если у вас вообще не установлен Python, то вот руководство по установке для WIndows. Следуйте ему а потом вернитесь к этой статье.

Установка IDE Python на компьютер

Многое в вашей работе как разработчика зависит от того, какую программу вы выбрали для написания кода. Хорошая интегрированная среда разработки (IDE) или редактор кода могут значительно повысить производительность труда.

В настоящее время Visual Studio Code стал основным редактором кода для всех языков и платформ. Но для простоты мы будем использовать PyCharm.

Профессиональная версия IDE может стоить 89,00 долл. в год, но существует и бесплатная версия для сообщества, с открытым исходным кодом. Перейдите на страницу загрузки PyCharm.

Страница загрузки PyCharm

Используйте кнопку «Скачать» для загрузки версии для сообщества. Размер файла должен быть чуть больше 350 мегабайт.

Под Windows вы получите исполняемый инсталлятор, под macOS — образ диска Apple, а под Linux — архив TAR.

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

После установки можно запустить IDE. При первом запуске вам будет предложено настроить некоторые параметры. Я бы посоветовал оставить настройки по умолчанию.

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

Экран «Добро пожаловать в PyCharm» с опциями начала нового проекта, открытия проекта или получения проекта из вашего VCS

Как создать новый проект в PyCharm

Если у вас открыто окно приветствия из предыдущего раздела, нажмите на кнопку «Новый проект».

Начните новый проект в PyCharm.

На следующем шаге выберите место для хранения проекта:

В поле ввода location часть HelloWorld является именем проекта. Убедитесь, что выбрана опция «New environment using Virtualenv». Также проверьте, чтобы в раскрывающемся списке «Base interpreter» была выбрана правильная версия Python.

Virtualenv — это программа, позволяющая создавать изолированные среды Python на основе заданного базового интерпретатора. Это очень полезно, поскольку в дальнейшем, когда вы будете работать над несколькими проектами на Python, их зависимости могут конфликтовать друг с другом.

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

Поскольку это, возможно, ваш первый проект на Python, я бы посоветовал оставить отмеченной опцию «Создать приветственный скрипт main.py». После того как вы будете удовлетворены выбором, нажмите кнопку «Создать».

Процесс создания проекта не должен занять много времени. После этого IDE автоматически откроет проект.

Окно PyCharm с открытым проектом

Для запуска кода можно использовать кнопку воспроизведения в правом верхнем углу. По умолчанию кнопка настроена на запуск файла «main.py».

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

Кнопка "main"

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

Как написать программу Hello World на Python

Продолжая предыдущий раздел, откройте файл «main.py» и замените весь код в нем на следующую строку:

print('Hello, World!')

Функция print() выводит все, что вы передаете в скобках. Не обязательно называть свой Python-файл «main.py». Это просто способ дать вам понять, что это точка входа в данную программу.

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

def main():
    print('Hello, World!')


if __name__ == '__main__':
    main()

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

Чтобы смоделировать более крупный проект, создайте еще один Python-файл, щелкнув правой кнопкой мыши на имени проекта «HelloWorld» и выбрав пункт «Python File» во вложенном меню «New».

Окно PyCharm  с открытыми выпадающими списками для выбора "Python File"

Назовите свой файл как-нибудь вроде «library» и нажмите клавишу Enter, пока в списке типов файлов выделено «Python file».

В папке проекта появится новый файл с именем «library.py». Поместите в этот файл следующие строки кода:

def greet():
    print('Hello, World!')

Это очень простая функция, которая выводит на консоль сообщение «Hello, World!». Вы можете импортировать и использовать эту функцию в своем файле «main.py».

Для этого необходимо обновить код файла «main.py» следующим образом:

from library import greet


def main():
    greet()


if __name__ == '__main__':
    main()

Вы импортируете функцию greet() из файла «library.py» и выполняете ее внутри функции main().

В вашем проекте в настоящее время есть два типа файлов Python. У вас есть файл «main.py», который является сценарием. Иными словами, этот файл можно выполнить.

Еще у вас есть файл «library.py», который является библиотекой. Иными словами, он содержит ряд полезных функций и переменных, которые можно импортировать в другие файлы Python.

Теперь представьте себе, что у вас в проекте сотни файлов, и они выглядят более или менее одинаково. Как бы кто-то другой нашел точку входа в программу?

Наиболее простым способом является поиск строки if __name__ == '__main__' по всему проекту. Это сделает ваш код гораздо более читабельным.

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

Переменная __name__ является специальной переменной Python. В случае скрипта значением этой переменной будет __main__ а в случае библиотеки ее значением будет имя этого файла.

Так, в приведенной выше программе значением __name__ внутри файла «main.py» будет __main__, а внутри файла «library.py» — library.

Если вы измените имя файла main.py на какое-либо другое, то значение все равно будет __main__, потому что это скрипт.

Однако ничто не мешает файлу «library.py» быть скриптом. Если запустить этот файл, то он станет скриптом.

В таких языках, как C/C++/Go/Java, у вас будет определенная функция main. Эта функция будет являться точкой входа в программу.

Поскольку в Python ничего подобного нет, использование выражения if __name__ == '__main__' усиливает ощущение заданной точки входа в программу.

Это выражение сообщает программисту и IDE, что данный скрипт предназначен для выполнения (а не для импорта в другие файлы Python).

Как инициализировать и опубликовать Git-репозиторий из PyCharm

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

Для работы с git в нашей IDE нам нужна вкладка «Контроль версий».

Окно PyCharm, вкладка Version Control на панели снизу

Щелкните на ней, и вы перейдете на вкладку «Контроль версий». Теперь щелкните на ссылке «Создать Git-репозиторий…».

Окно PyCharm, ссылка "Create Git repository..."

PyCharm спросит вас, где вы хотите инициализировать новый репозиторий. Убедитесь, что вы выбрали правильную папку.

Окно выбора папки для нового репозитория

После нажатия кнопки «OK» вкладка «Контроль версий» изменится на вкладку «Git».

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

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

Вид сайта gitignore.io. В поле отмечены "Python" и "PyCharm", справа - кнопка "Create".

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

На сайте появится содержимое нужного вам файла «.gitignore». Выберите и скопируйте все оттуда и вернитесь в PyCharm.

Далее создайте новый файл в проекте, щелкнув правой кнопкой мыши на имени проекта «HelloWorld» и выбрав пункт «File» в подменю «New».

Создание нового файла

Назовите свой файл «.gitignore» и нажмите клавишу Enter. PyCharm спросит, нужно ли добавить этот файл в Git. Щелкните на Add и вставьте скопированное содержимое.

На данный момент в вашем репозитории нет ни одного коммита. Чтобы создать новую фиксацию, щелкните на ссылке «Commit local changes» или переключитесь на вкладку «Commit».

Поскольку это ваш первый коммит, отметьте все файлы на вкладке «Commit».

Напишите сообщение коммита, чтобы было понятно, что это первый коммит, например «Initial commit», и нажмите кнопку «Commit» для завершения фиксации.

Вы успешно выполнили фиксацию в локальном репозитории. Теперь вы можете детально просмотреть все коммиты в мастер-ветке.

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

Затем скопируйте SSH-ссылку на этот репозиторий. Если у вас не настроен SSH для вашего проекта, вы можете использовать HTTPS-ссылку, но я настоятельно рекомендую использовать SSH.

Теперь вернитесь в PyCharm и посмотрите в правый верхний угол. Там, где написано Git, вы найдете несколько знаков.

Синяя стрелка «вниз» приведет к извлечению кода из удаленного репозитория, знак галочки — к созданию нового коммита, зеленая стрелка «вверх» — к переносу кода.

Значок часов покажет историю коммитов, а стрелка, направленная назад, вернёт изменения. Щелкните на стрелке «push», и на экране появится новое окно.

Щелкните на ссылке «Define remote» и в поле ввода URL вставьте ссылку, скопированную с GitHub. Нажмите кнопку OK и дождитесь окончания процесса.

Если все прошло нормально, PyCharm выдаст вам кнопку «Push». Загрузка кода на удаленный репозиторий займет не более нескольких секунд.

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

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

Окно GitHub с открытым репозиторием

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

Например, удалите файл «library.py» и обновите код в файле «main.py», чтобы он выводил на консоль сообщение «Hello, World!».

def main():
    print("Hello, World!")


if __name__ == '__main__':
    main()

После внесения изменений переключитесь на вкладку commit, и вы увидите все незафиксированные изменения.

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

Затем, вместо того чтобы просто зафиксировать изменения, попробуйте на этот раз нажать кнопку «Commit and Push…». Появится новое окно.

Если все выглядит хорошо, нажмите кнопку «Push» и дождитесь окончания процесса.

Помните, что при использовании HTTPS вам, возможно, придется повторно вводить свой e-mail и пароль при каждом push.

Вы можете проверить свой удаленный репозиторий на GitHub, чтобы убедиться, что push был выполнен правильно.

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

Работа с переменными и различными типами данных в Python

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

Чтобы создать новую переменную в Python, достаточно набрать ее имя, затем знак равенства и значение.

def main():
    book = 'Dracula'
    author = 'Bram Stoker'
    release_year = 1897
    goodreads_rating = 4.01

    print(book)
    print(author)
    print(release_year)
    print(goodreads_rating)


if __name__ == '__main__':
    main()


# Вывод программы:

# Dracula
# Bram Stoker
# 1897
# 4.01

Когда дело касается именования переменных, стандарт PEP 8 — Руководство по стилю для Python, гласит:

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

И еще:

Имена переменных соответствуют тем же соглашениям, что и имена функций.

В руководстве говорится:

Никогда не используйте символы ‘l’ (строчная буква эл), ‘O’ (заглавная буква о) или ‘I’ (заглавная буква ай) в качестве имен односимвольных переменных. В некоторых шрифтах эти символы неотличимы от цифр один и ноль. Если возникает соблазн использовать ‘l’, используйте вместо него ‘L’.

При соблюдении этих рекомендаций объявление переменных в Python очень простое.

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

def main():
    book, author, release_year, goodreads_rating = 'Dracula', 'Bram Stoker', 1897, 4.01

    print(book)
    print(author)
    print(release_year)
    print(goodreads_rating)


if __name__ == '__main__':
    main()
    
# Dracula
# Bram Stoker
# 1897
# 4.01

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

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

Более того, можно вывести их все сразу. Метод print() может принимать несколько параметров через запятые.

def main():
    book, author, release_year, goodreads_rating = 'Dracula', 'Bram Stoker', 1897, 4.01

    print(book, author, release_year, goodreads_rating)


if __name__ == '__main__':
    main()
    
# Dracula Bram Stoker 1897 4.01

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

Что касается print(), вы можете использовать знак + для объединения переменных со строками внутри этого метода. Но учтите, что это будет вызывать ошибку в случае, если мы захотим присоединить число:

def main():
    book, author, release_year, goodreads_rating = 'Dracula', 'Bram Stoker', 1897, 4.01

    print(book + ' is a novel by ' + author + ', published in ' + release_year + '. It has a rating of ' + goodreads_rating + ' on goodreads.')


if __name__ == '__main__':
    main()


# TypeError: can only concatenate str (not "int") to str

Если вы попытаетесь выполнить этот код, то получите TypeError с сообщением о том, что Python может конкатенировать или складывать строки, но не целые числа.

В приведенном фрагменте кода  book,  author,  release_year и goodreads_rating являются переменными разных типов.

Переменные book и author являются строками. Переменная release_year является целым числом, и, наконец, переменная goodreads_rating является числом с плавающей точкой.

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

Наиболее простым способом решения этой проблемы является преобразование числовых типов в строковые. Это можно сделать, вызвав у числовых переменных метод str() .

def main():
    book, author, release_year, goodreads_rating = 'Dracula', 'Bram Stoker', 1897, 4.01

    print(book + ' is a novel by ' + author + ', published in ' + str(release_year) + '. It has a rating of ' + str(goodreads_rating) + ' on goodreads.')


if __name__ == '__main__':
    main()

# Dracula is a novel by Bram Stoker, published in 1897. It has a rating of 4.01 on goodreads.

Это уже лучше — но можно сделать эту строку кода еще более читаемой, используя f-строку.

def main():
    book, author, release_year, goodreads_rating = 'Dracula', 'Bram Stoker', 1897, 4.01

    print(f'{book} is a novel by {author}, published in {release_year}. It has a rating of {goodreads_rating} on goodreads.')


if __name__ == '__main__':
    main()

# Dracula is a novel by Bram Stoker, published in 1897. It has a rating of 4.01 on goodreads.

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

Есть еще один момент, который не дает мне покоя, — это длина самой строки кода. К счастью, длинные строки можно разбить на несколько более коротких следующим образом:

def main():
    book, author, release_year, goodreads_rating = 'Dracula', 'Bram Stoker', 1897, 4.01

    print(f'{book} is a novel by {author}, published in {release_year}.'
          f' It has a rating of {goodreads_rating} on goodreads.')


if __name__ == '__main__':
    main()

# Dracula is a novel by Bram Stoker, published in 1897. It has a rating of 4.01 on goodreads.

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

Кроме int и float, в Python существует еще один числовой тип, называемый complex. Он был специально разработан для работы с числами типа 500+2j.

Существуют также булевы переменные, которые могут содержать значение True или False и ничего больше.

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

Работа с числами в Python

Простые числа в Python бывают двух типов. Целые числа — integer, и числа с плавающей точкой — float.

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

Система исчисленияПредставление
Десятичная404
Шестнадцатеричная0x194
Восьмеричная0o624
Бинарная0b000110010100

Таким образом, значение 404 можно представить в шестнадцатеричной, восьмеричной или двоичной системе с помощью префикса 0x0o или 0b соответственно.

Что касается чисел с плавающей точкой, в Python можно представлять их с точностью до 15 значащих цифр. Любая цифра после 15-го места может быть неточной.

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

def main():
    num_1 = 15
    num_2 = 12

    print(f'sum of num_1 and num_2 is: {num_1 + num_2}')
    print(f'difference of num_1 and num_2 is: {num_1 - num_2}')

if __name__ == '__main__':
    main()

# sum of num_1 and num_2 is: 27
# difference of num_1 and num_2 is: 3

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

def main():
    num_1 = 15
    num_2 = 12

    print(f'difference of num_2 and num_1 is: {num_2 - num_1}')

if __name__ == '__main__':
    main()

# difference of num_2 and num_1 is: -3

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

def main():
    num_1 = 15
    num_2 = 12

    print(f'product of num_1 and num_2 is: {num_1 * num_2}')
    print(f'quotient of num_1 and num_2 is: {num_1 / num_2}')
    print(f'floored quotient of num_1 and num_2 is: {num_1 // num_2}')


if __name__ == '__main__':
    main()

# product of num_1 and num_2 is: 180
# quotient of num_1 and num_2 is: 1.25
# floored quotient of num_1 and num_2 is: 1

Следует помнить, что в Python нельзя делить число на ноль. Если вы попытаетесь это сделать, то получите ошибку ZeroDivisionError  (подробнее об этом позже).

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

def main():
    num_1 = 15
    num_2 = 12

    print(f'floored quotient of num_1 and num_2 is: {num_1 // num_2}')


if __name__ == '__main__':
    main()

# floored quotient of num_1 and num_2 is: 1

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

Последняя операция, которую мы обсудим, — это нахождение остатка от операции деления.

def main():
    num_1 = 15
    num_2 = 12

    print(f'remainder of num_1 / num_2 is: {num_1 % num_2}')


if __name__ == '__main__':
    main()

# remainder of num_1 / num_2 is: 3

Эта операция также называется операцией взятия остатка или модуля. Так что, если кто-то упоминает оператор модуля или модуль, он имеет в виду знак процента (%).

Положительное число можно превратить в отрицательное, просто добавив перед ним знак -.

Также можно свободно преобразовывать целые числа в числа с плавающей точкой и наоборот.

def main():
    float_variable = 1.25
    integer_variable = 55

    print(f'{float_variable} converted to an integer is: {int(float_variable)}')
    print(f'{integer_variable} converted to a float is: {float(integer_variable)}')


if __name__ == '__main__':
    main()

# 1.25 converted to an integer is: 1
# 55 converted to a float is: 55.0

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

Методы int() и float() можно использовать и для строк (подробнее об этом позже).

Любая арифметическая операция с переменной float всегда дает результат типа float, если только он не преобразуется в integer явно.

def main():
    float_variable = 5.0
    integer_variable = 55

    print(f'the sum of {float_variable} and {integer_variable} is: {float_variable + integer_variable}')
    print(f'the sum of {float_variable} and {integer_variable} '
          f'converted to integer is: {int(float_variable + integer_variable)}')


if __name__ == '__main__':
    main()

# the sum of 5.0 and 55 is: 60.0
# the sum of 5.0 and 55 converted to integer is: 60

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

def main():
    num_1 = -5.8

    print(f'the absolute value of {num_1} is: {abs(num_1)}')


if __name__ == '__main__':
    main()

# the absolute value of -5.8 is: 5.8

Существует еще метод pow(x, y), который вы можете использовать для возведения числа x в степень y, как показано ниже.

def main():
    x = 2
    y = 3

    print(f'{2} to the power of {3} is: {pow(2, 3)}')
    print(f'{2} to the power of {3} is: {2 ** 3}')


if __name__ == '__main__':
    main()

# 2 to the power of 3 is: 8
# 2 to the power of 3 is: 8

Ту же операцию можно выполнить с помощью двух операторов умножения, но я всегда предпочитаю метод pow().

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

def main():
    num_1 = 8
    num_2 = 2

    print(f'division and modulus of {num_1} and {num_2} is: {divmod(num_1, num_2)}')


if __name__ == '__main__':
    main()

# division and modulus of 8 and 2 is: (4, 0)

Метод divmod(x, y) возвращает кортеж, содержащий два значения: результат целочисленного деления x на y (целую часть результата деления) и остаток от этого деления.

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

Прием входных данных от пользователей

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

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

def main():
    name = input('What is your name? ')

    print(f'Nice to meet you {name}')


if __name__ == '__main__':
    main()
    
# What is your name? Farhan
# Nice to meet you Farhan

Встроенный метод input() принимает единственный параметр, prompt, который является строкой. Все, что вы укажете в качестве значения этого параметра, будет отображено в консоли. Например, в данном случае «What is your name?» — это подсказка.

Как только пользователь введет что-либо в консоли и нажмет Enter, метод input() вернет это значение как строку.

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

def main():
    name = input('What is your name? ')
    age = input(f'How old are you {name}? ')
    current_year = input(f'What year is this again? ')

    print(f'If my calculations are right, you were born in {current_year - age}')


if __name__ == '__main__':
    main()

# What is your name? Farhan
# How old are you Farhan? 27
# What year is this again? 2023
# TypeError: unsupported operand type(s) for -: 'str' and 'str'

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

Для решения этой проблемы достаточно привести вводимые пользователем данные к числовым типам с помощью методов int() или float().

def main():
    name = input('What is your name? ')
    age = int(input(f'How old are you {name}? '))
    current_year = int(input(f'What year is this again? '))

    print(f'If my calculations are right, you were born in {current_year - age}')


if __name__ == '__main__':
    main()

# What is your name? Farhan
# How old are you Farhan? 27
# What year is this again? 2023
# If my calculations are right, you were born in 1996

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

def main():
    temperature_in_celsius = input('What is the temperature in celsius? ')

    temperature_in_fahrenheit = (float(temperature_in_celsius) * 1.8) + 32

    print(f'{temperature_in_celsius} degree celsius is equivalent to {temperature_in_fahrenheit} degree fahrenheit.')


if __name__ == '__main__':
    main()

# What is the temperature in celsius? 32
# 32 degree celsius is equivalent to 89.6 degree fahrenheit.

Эта программа может преобразовывать температуру из градусов Цельсия в градусы Фаренгейта. В этой программе я не сразу привожу строку к числовому типу данных. Я выполнил это преобразование во время вычисления, оставив исходную переменную ввода нетронутой. Также обратите внимание на использование функции float() вместо int().

Работа со строками в Python

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

В Python, всё, что находится внутри одинарных, двойных или тройных кавычек, считается строкой. Строки представляют собой последовательности байтов, представляющих символы Unicode.

def main():
    book = 'Dracula'
    author = "Bram Stoker"

    print('Title:', book)
    print('Author:', author)


if __name__ == '__main__':
    main()

# Title: Dracula
# Author: Bram Stoker

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

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

def main():
    question = "What's your name?"

    print(question)


if __name__ == '__main__':
    main()

# What's your name?

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

def main():
    sentence = 'Harriet Jacobs writes, "She sat down, quivering in every limb"'

    print(sentence)


if __name__ == '__main__':
    main()

# Harriet Jacobs writes, "She sat down, quivering in every limb"

При желании можно использовать последовательности символов, но PEP 8 — Style Guide for Python Code рекомендует избегать использования обратных слешей в строках.

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

def main():
    synopsis = """Dracula comprises journal entries, letters, and telegrams written by the main characters.
It begins with Jonathan Harker, a young English lawyer, as he travels to Transylvania.
Harker plans to meet with Count Dracula, a client of his firm, in order to finalize a property transaction.
When he arrives in Transylvania, the locals react with terror after he discloses his destination: Castle Dracula.
Though this unsettles him slightly, he continues onward.
The ominous howling of wolves rings through the air as he arrives at the castle.
When Harker meets Dracula, he acknowledges that the man is pale, gaunt, and strange.
Harker becomes further concerned when, after Harker cuts himself while shaving, Dracula lunges at his throat.
Soon after, Harker is seduced by three female vampires, from whom he barely escapes.
He then learns Dracula’s secret—that he is a vampire and survives by drinking human blood.
Harker correctly assumes that he is to be the count’s next victim.
He attacks the count, but his efforts are unsuccessful.
Dracula leaves Harker trapped in the castle and then, along with 50 boxes of dirt, departs for England."""

    print('Synopsis:', synopsis)


if __name__ == '__main__':
    main()

# Synopsis: Dracula comprises journal entries, letters, and telegrams written by the main characters.
# It begins with Jonathan Harker, a young English lawyer, as he travels to Transylvania.
# Harker plans to meet with Count Dracula, a client of his firm, in order to finalize a property transaction.
# When he arrives in Transylvania, the locals react with terror after he discloses his destination: Castle Dracula.
# Though this unsettles him slightly, he continues onward.
# The ominous howling of wolves rings through the air as he arrives at the castle.
# When Harker meets Dracula, he acknowledges that the man is pale, gaunt, and strange.
# Harker becomes further concerned when, after Harker cuts himself while shaving, Dracula lunges at his throat.
# Soon after, Harker is seduced by three female vampires, from whom he barely escapes.
# He then learns Dracula’s secret—that he is a vampire and survives by drinking human blood.
# Harker correctly assumes that he is to be the count’s next victim.
# He attacks the count, but his efforts are unsuccessful.
# Dracula leaves Harker trapped in the castle and then, along with 50 boxes of dirt, departs for England.

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

Вы можете объявить строку с тройными кавычками, используя три одинарные кавычки, но PEP 8 — Style Guide for Python Code рекомендует использовать именно три двойные кавычки.

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

Последовательности в Python

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

Списки в Python

Список в Python — именно то, чем кажется: коллекция данных, хранящихся последовательно в виде списка в памяти компьютера.

В Python можно создать новый список при помощи квадратных скобок, либо метода list(), передав в него элементы списка через запятую:

def main():
    horror_books = ['Dracula', 'Carmilla', 'The Imago Sequence']

    print(horror_books)


if __name__ == '__main__':
    main()

# ['Dracula', 'Carmilla', 'The Imago Sequence']

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

def main():
    a_random_list = ['Dracula', 1, 5.7, 'Carmilla']

    print(a_random_list)


if __name__ == '__main__':
    main()

# ['Dracula', 1, 5.7, 'Carmilla']

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

Списки в Python являются изменяемыми (мутабельными). Это означает, что вы можете изменять список после его создания. Например, можно использовать метод pop() для удаления последнего значения в списке.

def main():
    horror_books = ['Dracula', 'Carmilla', 'The Imago Sequence']

    print(horror_books.pop())
    print(horror_books)


if __name__ == '__main__':
    main()

# The Imago Sequence
# ['Dracula', 'Carmilla']

Как видно, метод pop() возвращает последнее значение из списка и удаляет его оттуда. В противовес pop() существует метод append()  для вставки нового элемента в список. Как видно из названия метода, он добавляет новый элемент в конец списка.

def main():
    horror_books = ['Dracula', 'Carmilla', 'The Imago Sequence']

    print(horror_books)

    horror_books.append('The Exorcist')

    print(horror_books)


if __name__ == '__main__':
    main()
    
# ['Dracula', 'Carmilla', 'The Imago Sequence']
# ['Dracula', 'Carmilla', 'The Imago Sequence', 'The Exorcist']

Учитывая мутабельность списков, их также можно сортировать.

Кортежи в Python

Списки — не единственный тип последовательности в Python. Ближайшим родственником списка является кортеж.

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

def main():
    horror_books = ('Dracula', 'Carmilla', 'The Imago Sequence')

    print(horror_books)


if __name__ == '__main__':
    main()

# ('Dracula', 'Carmilla', 'The Imago Sequence')

Точно так же, как и в списках, в кортежах вы можете смешивать разные типы данных.

def main():
    a_random_list = ('Dracula', 1, 5.7, 'Carmilla')

    print(a_random_list)


if __name__ == '__main__':
    main()

# ('Dracula', 1, 5.7, 'Carmilla')

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

Диапазоны в Python

Последний тип последовательности, с которым мы познакомимся в этом разделе, — это диапазон (range). Диапазон в Python — это просто диапазон чисел.

Вы можете создать диапазон, вызвав метод range(), который вернет вам диапазон чисел. Этот метод можно вызвать несколькими способами.

Наиболее распространенным является передача в качестве параметра одного числа. В этом случае метод будет рассматривать это число как конец диапазона, а 0 — как начало.

def main():
    a_range = range(10)

    print(a_range)

    list_a_range = list(a_range)

    print(list_a_range)


if __name__ == '__main__':
    main()

# range(0, 10)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Вывод диапазона как такового не даст вам много информации. Придется преобразовать диапазон в список или кортеж, вызвав list() или tuple().

После преобразования можно вывести весь диапазон в консоль. Обратите внимание, что 10 (число которое мы передали в метод range()) не входит в диапазон.

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

def main():
    a_range = range(5, 15)

    print(a_range)

    list_a_range = list(a_range)

    print(list_a_range)

    tuple_a_range = tuple(a_range)

    print(tuple_a_range)


if __name__ == '__main__':
    main()

# range(5, 15)
# [5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
# (5, 6, 7, 8, 9, 10, 11, 12, 13, 14)

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

Третий и последний способ вызова метода — это также определение шага. Например, представьте, что вам нужен диапазон, состоящий из всех нечетных чисел в пределах от 1 до 10.

def main():
    a_range = range(1, 10, 2)

    print(a_range)

    list_a_range = list(a_range)

    print(list_a_range)

    tuple_a_range = tuple(a_range)

    print(tuple_a_range)


if __name__ == '__main__':
    main()

# range(1, 10, 2)
# [1, 3, 5, 7, 9]
# (1, 3, 5, 7, 9)

Поскольку в данном случае значение шага равно 2, диапазон будет начинаться с 1, но затем пропускать каждое второе число.

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

Как работает индексирование в Python

Один из наиболее важных концептов, связанных с последовательностями, которые вам нужно понимать — это индексация.

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

horror-books-list

Данная таблица представляет собой список книг ужасов. Индекс первой книги равен 0 — это означает, что первый элемент находится на 0-м месте.

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

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

def main():
    horror_books = ['Dracula', 'Carmilla', 'The Imago Sequence']

    print(horror_books[0])
    print(horror_books[1])
    print(horror_books[2])


if __name__ == '__main__':
    main()

# Dracula
# Carmilla
# The Imago Sequence

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

def main():
    books = ['Dracula', 'Frankenstein', 'The Omen', 'The Exorcist', 'The Legend of Sleepy Hollow',
             'And Then There Were None', 'The ABC Murders', 'The Valley of Fear']

    print(books[0])

    print(books[1])
    print(books[-1])

    print(books[2])
    print(books[-2])


if __name__ == '__main__':
    main()

# Dracula

# Frankenstein
# The Valley of Fear

# The Omen
# The ABC Murders

0-й элемент в списке всегда будет первым. Теперь, если обратиться к элементу, находящемуся на 1-й позиции, то получится «Frankenstein».

Но если попытаться обратиться к элементу на -1-й позиции, то получится «The Valley of Fear», поскольку это первый элемент в обратном порядке.

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

Нулевая индексация представлена в виде круговой диаграммы, подобной часам

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

Итерируемые типы и их использование в циклах в Python

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

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

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

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

def main():
    random_numbers = [6, 1, 3, 8, 0, 9, 12, 3, 4, 0, 54, 8, 100, 55, 60, 70, 85]

    for number in random_numbers:
        print(number)

if __name__ == '__main__':
    main()

# 6
# 1
# 3
# 8
# 0
# 9
# 12
# 3
# 4
# 0
# 54
# 8
# 100
# 55
# 60
# 70
# 85

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

Хотя вы пишете это как for number, Python интерпретирует это как «для каждого числа» и задается вопросом, где находятся эти числа.

Именно тогда вы говорите in, за которым следует имя последовательности, в данном случае random_numbers.

Теперь Python понимает, что вы хотите сделать что-то с каждым числом в последовательности random_numbers, но что именно?

Это то, что вы должны написать после двоеточия. Будьте очень внимательны к отступам. Все, что имеет отступ на один уровень после объявления цикла for, считается телом цикла.

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

Поскольку в последовательности есть 17 чисел, цикл будет выполняться 17 раз, и каждый раз у number будет новое значение.

Выполнение начнется с индекса 0, который имеет значение 6, и пройдет по индексам 1, 2, 3, 4, 5 и так далее.

На каждой итерации Python сохранит значение переменной, расположенной по индексу, над которым в данный момент работает, и запишет это значение в number. Таким образом, вы получите длинный список чисел.

Вместо вывода исходного значения вы можете умножить его на 2 и вывести результат.

def main():
    random_numbers = [6, 1, 3, 8, 0, 9, 12, 3, 4, 0, 54, 8, 100, 55, 60, 70, 85]

    for number in random_numbers:
        print(number * 2)

if __name__ == '__main__':
    main()

# 12
# 2
# 6
# 16
# 0
# 18
# 24
# 6
# 8
# 0
# 108
# 16
# 200
# 110
# 120
# 140
# 170

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

def main():
    random_numbers = [6, 1, 3, 8, 0, 9, 12, 3, 4, 0, 54, 8, 100, 55, 60, 70, 85]
    multiplied_random_numbers = []

    for number in random_numbers:
        multiplied_random_numbers.append(number * 2)

    print(multiplied_random_numbers)

if __name__ == '__main__':
    main()

# [12, 2, 6, 16, 0, 18, 24, 6, 8, 0, 108, 16, 200, 110, 120, 140, 170]

Для этого вам понадобится пустой список. Затем, после умножения числа, можно просто вызвать метод append() нового списка и передать умноженное значение.

Наконец, убедитесь, что метод print находится вне тела цикла, иначе в итоге список будет выведен 17 раз.

Цикл for работает со всеми типами последовательностей и любыми итерируемыми объектами в языке Python. Но что же такое эти итерируемые объекты?

В Python любой объект, имеющий метод __iter__(), считается итерируемым.

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

def main():
    random_numbers = [6, 1, 3, 8, 0, 9, 12, 3, 4, 0, 54, 8, 100, 55, 60, 70, 85]

    print(dir(random_numbers))

if __name__ == '__main__':
    main()

# ['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

Вы можете увидеть некоторые знакомые методы, такие как appendcount, и index, но самое главное — в нем есть метод __iter__.

Продолжая работать в Python, вы со временем запомните типы, поддерживаемые циклом for, но вы всегда можете использовать метод dir() на объекте, чтобы выяснить это.

Как использовать циклы while

В Python существует еще один тип циклов, известный как цикл while. В отличие от for, цикл while может выполнять оператор до тех пор, пока заданное условие оценивается как True.

def main():
    number = 1
    while number < 11:
        print(number)
        number += 1

if __name__ == '__main__':
    main()
    
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
# 9
# 10

Здесь имеется переменная number со значением 1 и цикл while, который выводит значение числа, а затем увеличивает его на 1.

Цикл while начинается с объявления while? за которым следует условие. Затем пишется тело цикла, начиная со следующей строки после двоеточия.

Циклы for  полезны, когда вы пытаетесь получить доступ к каждому элементу внутри итерируемого объекта. А циклы while полезны, когда вы хотите повторить один и тот же набор инструкций произвольное количество раз.

Строка number += 1 является другим способом записи number = number + 1 и очень часто используется программистами в различных языках программирования.

Вложенные циклы в Python

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

def main():
    for x in range(1, 6):
        print()
        for y in range(1, 11):
            print(f"{x} x {y} = {x * y}")


if __name__ == '__main__':
    main()

#
# 1 x 1 = 1
# 1 x 2 = 2
# 1 x 3 = 3
# 1 x 4 = 4
# 1 x 5 = 5
# 1 x 6 = 6
# 1 x 7 = 7
# 1 x 8 = 8
# 1 x 9 = 9
# 1 x 10 = 10
#
# 2 x 1 = 2
# 2 x 2 = 4
# 2 x 3 = 6
# 2 x 4 = 8
# 2 x 5 = 10
# 2 x 6 = 12
# 2 x 7 = 14
# 2 x 8 = 16
# 2 x 9 = 18
# 2 x 10 = 20
#
# 3 x 1 = 3
# 3 x 2 = 6
# 3 x 3 = 9
# 3 x 4 = 12
# 3 x 5 = 15
# 3 x 6 = 18
# 3 x 7 = 21
# 3 x 8 = 24
# 3 x 9 = 27
# 3 x 10 = 30
#
# 4 x 1 = 4
# 4 x 2 = 8
# 4 x 3 = 12
# 4 x 4 = 16
# 4 x 5 = 20
# 4 x 6 = 24
# 4 x 7 = 28
# 4 x 8 = 32
# 4 x 9 = 36
# 4 x 10 = 40
#
# 5 x 1 = 5
# 5 x 2 = 10
# 5 x 3 = 15
# 5 x 4 = 20
# 5 x 5 = 25
# 5 x 6 = 30
# 5 x 7 = 35
# 5 x 8 = 40
# 5 x 9 = 45
# 5 x 10 = 50

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

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

Здесь x представляет собой левый операнд или постоянный, а y — правый операнд или переменный.

Первый цикл перебирает диапазон от 1 до 5, а второй цикл перебирает диапазон от 1 до 10.

Поскольку конечное число диапазона исключено, вам нужно указать число, которое на 1 больше желаемого конечного числа.

Сначала интерпретатор Python встречает внешний цикл и начинает его выполнение. Пока интерпретатор находится внутри этого цикла, значение x равно 1.

Затем интерпретатор встречает внутренний цикл и начинает его выполнение. Внутри внутреннего цикла значение x остается 1, но значение y увеличивается с каждой итерацией.

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

После завершения 10 итераций внутреннего цикла интерпретатор возвращается к внешнему циклу и начинает его выполнение снова.

На этот раз значение x становится равным 2, так как это следующее число в диапазоне.

Таким образом, внешний цикл выполняется 5 раз, а внутренний цикл выполняется 10 раз для каждой из этих итераций.

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

Я бы порекомендовал вам реализовать код, написанный выше, используя циклы while, чтобы проверить ваше понимание.

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

Например, если пользователь вводит 5 и 10 в качестве входных данных, выведите таблицы умножения для всех чисел от 5 до 10.

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

Общие операции с последовательностями в Python

Вы уже знакомы с четырьмя наиболее популярными типами последовательностей в Python. Так что я думаю, пришло время узнать некоторые общие операции, которые вы можете выполнять с ними. Давайте начнем, хорошо?

Оператор in

Оператор in является наиболее распространенным способом проверки наличия объекта в последовательности. Например, предположим, что у вас есть строка, и вы хотите проверить, содержит ли она слово «Red».

def main():
    a_string = 'Little Red Riding-Hood comes to me one Christmas Eve to give me information of the cruelty and ' \
               'treachery of that dissembling Wolf who ate her grandmother. '

    print('Red' in a_string)


if __name__ == '__main__':
    main()

# True

Это буквально то же самое, что спросить у Python, находится ли слово «Red» в  переменной a_string. В качестве ответа Python выдаст либо True, либо False.

Оператор in можно использовать не только для строк, но и для любых других типов коллекций, таких как списки, кортежи и диапазоны.

def main():
    books = ['Dracula', 'Frankenstein', 'The Omen', 'The Exorcist', 'The Legend of Sleepy Hollow']
    movies = ('A Christmas Carol', 'The Sea Beast', 'Enchanted', 'Pinocchio', 'The Addams Family')
    numbers = range(10)

    print('A Christmas Carol' in books)
    print('Enchanted' in movies)
    print(5 in numbers)


if __name__ == '__main__':
    main()

# False
# True
# True

«A Christmas Carol» не существует в списке books , поэтому мы получили  False. Два других утверждения верны, поэтому они True.

Можно также узнать, отсутствует ли значение в списке. Для этого можно использовать оператор not в сочетании с оператором in.

def main():
    books = ['Dracula', 'Frankenstein', 'The Omen', 'The Exorcist', 'The Legend of Sleepy Hollow']
    movies = ('A Christmas Carol', 'The Sea Beast', 'Enchanted', 'Pinocchio', 'The Addams Family')
    numbers = range(10)

    print('A Christmas Carol' not in books)
    print('Enchanted' not in movies)
    print(15 not in numbers)


if __name__ == '__main__':
    main()

# True
# False
# True

«A Christmas Carol» не присутствует в списке books, поэтому первое утверждение оценивается как True. Второе утверждение имеет значение False, так как фильм «Enchanted» присутствует в списке movies.

Последнее объясняется само собой. Операторы in и not in очень удобны при работе с условными операторами.

Как использовать операторы + и * с последовательностями в Python

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

Оператор + позволяет объединить две последовательности.

def main():
    books = ['Dracula', 'Frankenstein', 'The Omen', 'The Exorcist', 'The Legend of Sleepy Hollow']
    more_books = ['And Then There Were None', 'The ABC Murders', 'The Valley of Fear', 'The Hound of the Baskervilles', 'The Chestnut Man']


    print(books + more_books)


if __name__ == '__main__':
    main()

# ['Dracula', 'Frankenstein', 'The Omen', 'The Exorcist', 'The Legend of Sleepy Hollow', 'And Then There Were None', 'The ABC Murders', 'The Valley of Fear', 'The Hound of the Baskervilles', 'The Chestnut Man']

Как видно, оператор добавил содержимое списка books к содержимому списка more_books .

А оператор * создает несколько копий заданной последовательности.

def main():
    books = ['Dracula', 'Frankenstein', 'The Omen', 'The Exorcist', 'The Legend of Sleepy Hollow']


    print(books * 2)


if __name__ == '__main__':
    main()

# ['Dracula', 'Frankenstein', 'The Omen', 'The Exorcist', 'The Legend of Sleepy Hollow', 'Dracula', 'Frankenstein', 'The Omen', 'The Exorcist', 'The Legend of Sleepy Hollow']

Так, умножение списка books  на 2 дает нам все 5 книг в списке дважды.

Как использовать функции len(), min() и max() в Python

Функция len() может возвращать длину заданной последовательности. А функции  min() и max() могут возвращать минимальное и максимальное значение в заданной последовательности, соответственно.

def main():
    random_numbers = [6, 1, 3, 8, 0]


    print(len(random_numbers))
    print(min(random_numbers))
    print(max(random_numbers))


if __name__ == '__main__':
    main()

# 5
# 0
# 8

Поскольку в списке 5 элементов, то 5 — это результат вызова функции len().

Наименьшее значение в списке равно 0, а наибольшее — 8, что является результатом вызовов функций min() и max() соответственно.

Операции со строками в Python

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

Однако текстовые последовательности (такие как строки) имеют некоторые специальные методы, доступные для них.

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

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

Если вы хотите узнать обо всех доступных строковых методах, обратитесь к официальной документации по Python.

Как сделать буквы в строках заглавными

Первый метод, который вы узнаете, называется capitalize():

def main():
    country_name = 'bangladesh'

    print(country_name.capitalize())


if __name__ == '__main__':
    main()

# Bangladesh

Как видно из приведенного фрагмента кода, метод capitalize() превращает первую букву слова в заглавную.

Это просто, но давайте попробуем это сделать на строке, содержащей несколько слов.

def main():
    book_name = 'the house of silk'

    print(book_name.capitalize())


if __name__ == '__main__':
    main()

# The house of silk

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

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

def main():
    book_name = 'the house of silk'

    print(book_name.title())


if __name__ == '__main__':
    main()

# The House Of Silk

Однако проблема все же существует. Возьмем, например, следующую строку с апострофами.

def main():
    book_name = "alice's adventures in wonderland"

    print(book_name.title())


if __name__ == '__main__':
    main()

# Alice'S Adventures In Wonderland

Как видно, метод title() рассматривает следующий за апострофом символ s как отдельное слово и переводит его в верхний регистр.

По этому поводу в официальной документации говорится:

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

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

from string import capwords


def main():
    book_name = "alice's adventures in wonderland"

    print(capwords(book_name))


if __name__ == '__main__':
    main()

# Alice's Adventures In Wonderland

Обратите внимание на import в верхней части. Функция capwords() является не внутренним строковым методом, а функцией, которая находится внутри модуля string .

Более подробно о модулях и импорте вы узнаете позже. Пока же просто воспользуйтесь этой функцией. Хотя функция использует пробелы для разделения слов, ее можно изменить.

from string import capwords


def main():
    address = 'house 42, road 02, wonderland'

    print(capwords(address, ', '))


if __name__ == '__main__':
    main()

# House 42, Road 02, Wonderland

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

Функция capwords() может принимать в качестве второго параметра пользовательский разделитель. В качестве разделителя можно передать любую строку.

Наконец, существует метод istitle(), позволяющий проверить, находится ли заданная строка в регистре заголовка.

def main():
    book_name = 'hearts in atlantis'

    print(f'Is "{book_name}" in title case? {book_name.istitle()}')
    print(f'Is "{book_name.title()}" in title case? {book_name.title().istitle()}')


if __name__ == '__main__':
    main()

# Is "hearts in atlantis" in title case? False
# Is "Hearts In Atlantis" in title case? True

Однако следует помнить, что метод istitle() не работает со вспомогательной функцией capwords().

Как преобразовать строки в нижний или верхний регистр

Помимо приведения к заглавным буквам, вы можете захотеть преобразовать всю строку в верхний или нижний регистр. Для этого вы можете использовать методы Python upper() и lower().

def main():
    book_name = 'moriarty'

    print(book_name.upper())

    another_book_name = 'DRACULA'

    print(another_book_name.lower())


if __name__ == '__main__':
    main()

# MORIARTY
# dracula

Существуют также методы isupper() и islower() для проверки того, находится ли данная строка уже в одном из буквенных регистров.

def main():
    book_name = 'moriarty'

    print(book_name)
    print(f'Is {book_name} in upper case? {book_name.isupper()}')
    print(f'Is {book_name} in lower case? {book_name.islower()}')

    another_book_name = 'DRACULA'

    print(another_book_name)
    print(f'Is {another_book_name} in upper case? {another_book_name.islower()}')
    print(f'Is {another_book_name} in lower case? {another_book_name.isupper()}')


if __name__ == '__main__':
    main()

# moriarty
# Is moriarty in upper case? False
# Is moriarty in lower case? True
# DRACULA
# Is DRACULA in upper case? True
# Is DRACULA in lower case? False

Есть еще метод casefold(), который является как бы более агрессивной версией метода lower().

Согласно официальной документации:

Casefolding (приведение к форме регистра) подобно приведению к нижнему регистру, но более агрессивно, потому что его целью является удаление всех различий в регистре в строке. Например, немецкая строчная буква ‘ß’ эквивалентна «ss». Поскольку она уже в нижнем регистре, lower() не изменит ‘ß’; casefold() же выполнит преобразование.

Использование этого метода идентично использованию метода lower().

def main():
    book_name = 'DRACULA'

    print(book_name.casefold())


if __name__ == '__main__':
    main()

# dracula

Эти три метода хороши, но что, если вы не хотите использовать ни один из них, а просто хотите сменить регистр заданной строки?

Метод swapcase() может сделать именно это.

def main():
    book_name = 'HEARTS IN ATLANTIS'

    print(book_name.swapcase())


if __name__ == '__main__':
    main()

# hearts in atlantis

Как видно, метод преобразовал название книги в нижний регистр из верхнего.

Как подсчитать количество вхождений подстроки в строку в Python

Если необходимо узнать количество вхождений подстроки в строку, можно воспользоваться методом count().

def main():
    paragraph = '''At three in the morning the chief Sussex detective, obeying the urgent call from Sergeant Wilson of 
    Birlstone, arrived from headquarters in a light dog-cart behind a breathless trotter. By the five-forty train in 
    the morning he had sent his message to Scotland Yard, and he was at the Birlstone station at twelve o'clock to 
    welcome us. White Mason was a quiet, comfortable-looking person in a loose tweed suit, with a clean-shaved, 
    ruddy face, a stoutish body, and powerful bandy legs adorned with gaiters, looking like a small farmer, 
    a retired gamekeeper, or anything upon earth except a very favourable specimen of the provincial criminal 
    officer.'''

    substring = 'morning'

    print(f'The substring "{substring}" shows up {paragraph.count(substring)} times in the paragraph.')


if __name__ == '__main__':
    main()

# The substring "morning" shows up 2 times in the paragraph.

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

Как разделять и соединять строки в Python

В Python легко можно разбить строку на список слов или объединить список слов в строку.

def main():
    string = 'Holmes was certainly not a difficult man to live with'

    word_list = string.split()

    print(word_list)


if __name__ == '__main__':
    main()

# ['Holmes', 'was', 'certainly', 'not', 'a', 'difficult', 'man', 'to', 'live', 'with']

Если вызвать метод split() без параметров, то он разделит заданную строку на слова, используя пробелы в качестве разделителей.

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

def main():
    string = 'Holmes,was,certainly,not,a,difficult,man,to,live,with'

    word_list = string.split(',', 5)

    print(word_list)


if __name__ == '__main__':
    main()

# ['Holmes', 'was', 'certainly', 'not', 'a', 'difficult,man,to,live,with']

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

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

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

Методом, противоположным split(), является join(). Он работает с любыми итерируемыми объектами в Python.

def main():
    word_list = ['Holmes', 'was', 'certainly', 'not', 'a', 'difficult', 'man', 'to', 'live', 'with']
    string = ''

    string = string.join(word_list)

    print(string)

    word_list = ['Holmes', 'was', 'certainly', 'not', 'a', 'difficult', 'man', 'to', 'live', 'with']
    join_string = ' '

    string = join_string.join(word_list)

    print(string)


if __name__ == '__main__':
    main()

# Holmeswascertainlynotadifficultmantolivewith
# Holmes was certainly not a difficult man to live with

Вот и все. Обратите внимание, что метод join() вызывается у объекта, который мы используем в качестве «склейки». И если join_string будет равна ", ", то в итоговой строке элементы будут перечислены через запятую.

Условные операторы в Python

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

Надеюсь, вы помните логический тип данных из предыдущего раздела — тот, который может содержать только значения True или False.

Что ж, в Python вы можете использовать логический тип данных с оператором if (условным оператором), чтобы выполнять действия согласно условиям.

def main():
    number = int(input('what number would you like to check?\n- '))

    if number % 2 == 0:
        print(f"{number} is even.")
    else:
        print(f"{number} is odd.")


if __name__ == '__main__':
    main()

# what number would you like to check?
# - 10
# 10 is even.

Начните с написания if, за которым следует условие и двоеточие. Под условием я понимаю утверждение, которое оценивается как булево значение (True или False).

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

Так, если данное число делится на 2 и остаток равен 0, то это четное число. В противном случае оно будет нечетным.

Для выбора между двумя различными вариантами можно использовать операторы if и else. Если же необходимо выбрать несколько вариантов, то можно использовать еще и оператор elif, который будет проверять еще одно условие, если условие if было провалено.

def main():
    year = int(input('which year would you like to check?\n- '))

    if year % 400 == 0 and year % 100 == 0:
        print(f"{year} is leap year.")
    elif year % 4 == 0 and year % 100 != 0:
        print(f"{year} is leap year.")
    else:
        print(f"{year} is not leap year.")


if __name__ == '__main__':
    main()

# which year would you like to check?
# - 2004
# 2004 is leap year.

Оператор elif располагается после оператора if и перед оператором else .

Считайте, что это похоже на «else if», так что если оператор if не работает, то его место займет elif. Вы указываете условие в нем точно так же, как и в обычном  if-операторе.

Еще одним новым моментом в этом примере является оператор  and. Это один из логических операторов в Python.

Если выражения с обеих сторон оператора and оцениваются как True, то все выражение оценивается как True. Все просто.

Не волнуйтесь, если в данный момент вы не до конца понимаете, что такое оператор and. О нем и его братьях и сестрах вы узнаете в следующем разделе.

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

def main():
    number = int(input('what number would you like to check?\n- '))

    is_not_prime = False

    if number == 1:
        print(f"{number} is not a prime number.")
    elif number > 1:
        for n in range(2, number):
            if (number % n) == 0:
                is_not_prime = True
                break

        if is_not_prime:
            print(f"{number} is not a prime number.")
        else:
            print(f"{number} is a prime number.")


if __name__ == '__main__':
    main()

# what number would you like to check?
# - 10
# 10 is not a prime number.

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

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

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

Если данное число больше 1, то его нужно разделить на все числа от 2 до данного числа.

Если число делится на любое из этих чисел, то вы переводите переменную is_not_prime в True и завершаете цикл.

Оператор break просто немедленно выходит из цикла. Существует также оператор continue, который вместо выхода из цикла пропускает текущую итерацию.

Наконец, если переменная is_not_prime равна True, то число не является простым.

Таким образом, как вы видите, можно не только помещать циклы внутри условного оператора, но и помещать условные операторы внутри цикла.

Последний пример, который я хотел бы показать, это оператор for...else. Как видно из приведенного примера, у вас есть  оператор for, за которым следует оператор else.

def main():
    number = int(input('what number would you like to check?\n- '))

    if number == 1:
        print(f"{number} is not a prime number.")
    elif number > 1:
        for n in range(2, number):
            if (number % n) == 0:
                print(f"{number} is not a prime number.")
                break
        else:
            print(f"{number} is a prime number.")


if __name__ == '__main__':
    main()

# what number would you like to check?
# - 5
# 5 is a prime number.

Если вы поместите оператор else на один уровень с оператором for, то Python выполнит все, что вы поместите внутри блока else, как только цикл завершится.

Реляционные и логические операторы в Python

В приведенных выше примерах вы видели использование ==, а также and. В этом разделе мы поближе познакомимся с ними.

Реляционные операторы (операторы сравнения) могут быть полезны, когда необходимо проверить связь между двумя переменными. Существует шесть таких операторов:

ОператорЗначениеПример
==Равно5 == 5 даёт True, но 5 == 10 даёт False
!=Не равно5 != 10 даёт True, но 5 != 5 даёт  False
>Больше, чем10 > 5 даёт True, но 5 > 10 даёт False
<Меньше, чем5 < 10 даёт True, но 10 < 5 даёт False
>=Больше или равно10 >= 5 и 10 >= 10 даёт True, но 5 >= 10 даёт False
<=Меньше или равно5 <= 10 и 5 <= 5 даёт True, но 10 <= 5 даёт False

Оператор == использовался с самого начала. С другими операторами вы познакомитесь по мере продвижения вперед.

Кроме них, в Python существуют еще логические операторы: and,  or и not.

Чтобы продемонстрировать использование операторов, давайте представим ролевую игру, где для перехода на следующий уровень герой должен иметь щит 45-го или выше уровня и меч 48-го или выше уровня.

def main():
    shield = int(input('what is your shield level? '))
    sword = int(input('what is your sword level? '))

    if shield >= 45 and sword >= 48:
        print('you shall pass!')
    else:
        print('you shall not pass!')


if __name__ == '__main__':
    main()

# what is your shield level? 42
# what is your sword level? 52
# you shall not pass!

Если не выполнены оба условия, то оператор будет иметь значение False.

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

def main():
    shield = int(input('what is your shield level? '))
    sword = int(input('what is your sword level? '))
    armor = int(input('what is your armor level? '))

    if shield >= 45 and sword >= 48 and armor >= 25:
        print('you shall pass!')
    else:
        print('you shall not pass!')


if __name__ == '__main__':
    main()

# what is your shield level? 45
# what is your sword level? 50
# what is your armor level? 10
# you shall not pass!

Оператор or является более «щадящим». Если любое из заданных условий будет истинным, то и все утверждение будет истинным.

Например, в другой игре попасть в замок Дракулы можно только в том случае, если вам более 500 000 лет или вы официально мертвы.

def main():
    age = 10_000
    is_legally_dead = True

    if is_legally_dead or age > 500_000:
        print('you shall pass!')
    else:
        print('you shall not pass!')


if __name__ == '__main__':
    main()

# you shall pass!

Операторы and и or можно комбинировать. Я не буду перечислять все возможные комбинации, но по мере дальнейшей работы с Python вы познакомитесь с ними поближе.

Последний логический оператор, который я хотел бы рассмотреть, — это not. Этот оператор принимает только один операнд и возвращает противоположное значение.

def main():
    print('not True =', not True)
    print('not False =', not False)


if __name__ == '__main__':
    main()

# not True = False
# not False = True

Давайте изменим правила хоррор-игры, о которой мы говорили в предыдущем примере. Сделаем так, что в замок могут войти только те, кому больше 500 000 лет и кто не является Ван Хельсингом.

def main():
    age = 800_000
    is_van_helsing = True

    if age > 500_000 and not is_van_helsing:
        print('you shall pass!')
    else:
        print('you shall not pass!')


if __name__ == '__main__':
    main()

# you shall not pass!

Операторы присваивания в Python

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

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

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

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

ОператорИспользованиеЭквивалент
+=a += ba = a + b
-=a -= ba = a-b
*=a *= ba = a * b
/=a /= ba = a / b
%=a %= ba = a % b
**=a **= ba = a ** b

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

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

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

def main():
    start = int(input('which number do you want to start from?\n- '))
    end = int(input('which number do you want to stop at?\n- '))

    total = 0

    for number in range(start, end + 1):
        total += number

    print(f"the sum of the numbers between {start} and {end} is: {total}")


if __name__ == '__main__':
    main()

# which number do you want to start from?
# - 1
# which number do you want to stop at?
# - 10
# the sum of the numbers between 1 and 10 is: 55

Надеюсь, вы помните, что конечное число в вызове функции range() исключается. Поэтому мне пришлось добавить «+1» к конечному числу.

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

Множества в Python

К настоящему времени вы познакомились с несколькими итерируемыми типами, такими как списки, кортежи и строки. Существует еще один тип, известный как множество. Давайте рассмотрим пример:

def main():
    numbers = {1, 2, 3, 4, 5}

    for number in numbers:
        print(number)


if __name__ == '__main__':
    main()

# 1
# 2
# 3
# 4
# 5

Вы можете создать новое множество, поместив значения между фигурными скобками. Однако следует помнить, что с помощью фигурных скобок нельзя создать пустое множество. Для этого необходимо использовать функцию  set().

def main():
    numbers = {}

    print(type(numbers))

    numbers = set()

    print(type(numbers))


if __name__ == '__main__':
    main()

# <class 'dict'>
# <class 'set'>

Как видно, использование пустых фигурных скобок создает словарь, а вот функция set() — создает пустое множество.

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

def main():
    numbers_list = [1, 2, 3, 4, 5, 3, 2, 4]

    print(numbers_list)

    numbers_set = set(numbers_list)

    print(numbers_set)


if __name__ == '__main__':
    main()

# [1, 2, 3, 4, 5, 3, 2, 4]
# {1, 2, 3, 4, 5}

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

Множества являются мутабельными, поэтому в них можно добавлять новые значения с помощью метода  add().

def main():
    numbers = {1, 2, 3, 4, 5}

    numbers.add(500)

    print(numbers)


if __name__ == '__main__':
    main()

# {1, 2, 3, 4, 5, 500}

Аналогичным образом можно использовать метод discard() для удаления элемента из множества или метод clear() для полного удаления всех значений.

def main():
    numbers = {1, 2, 3, 4, 5}

    numbers.discard(3)

    print(numbers)

    numbers.clear()

    print(numbers)


if __name__ == '__main__':
    main()

# {1, 2, 4, 5}
# set()

Обратите внимание, что пустое множество отображается как set(), а не {}, так как {} указывает на пустой словарь.

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

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

Словари в Python

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

def main():
    programming_books = {
        'C Programming Language': 35,
        'Introduction to Algorithms': 100,
        'Clean Code: A Handbook of Agile Software Craftsmanship': 50
    }

    print(programming_books)


if __name__ == '__main__':
    main()

# {'C Programming Language': 35, 'Introduction to Algorithms': 100, 'Clean Code: A Handbook of Agile Software Craftsmanship': 50}

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

Внутри скобок находится множество пар ключ-значение. Строки в левой части — это ключи, а в правой — значения. Доступ к любому значению можно получить с помощью метода get(), передав в него ключ.

def main():
    programming_books = {
        'C Programming Language': 35,
        'Introduction to Algorithms': 100,
        'Clean Code: A Handbook of Agile Software Craftsmanship': 50
    }

    cpl = 'C Programming Language'
    algo = 'Introduction to Algorithms'

    print(f"The price of {cpl} is ${programming_books.get(cpl)}")
    print(f"The price of {algo} is ${programming_books[algo]}")


if __name__ == '__main__':
    main()

# The price of C Programming Language is $35
# The price of Introduction to Algorithms is $100

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

Словари являются мутабельными, то есть в них можно добавлять новые элементы, удалять или изменять существующие.

def main():
    programming_books = {
        'C Programming Language': 35,
        'Introduction to Algorithms': 100,
        'Clean Code: A Handbook of Agile Software Craftsmanship': 50
    }

    key = 'C Programming Language'

    programming_books[key] = 45

    programming_books['The Pragmatic Programmer'] = 32

    print(programming_books)


if __name__ == '__main__':
    main()

# {'C Programming Language': 45, 'Introduction to Algorithms': 100, 'Clean Code: A Handbook of Agile Software Craftsmanship': 50, 'The Pragmatic Programmer': 32}

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

Если в квадратных скобках указать несуществующий ключ, то мы создадим новую пару ключ-значение. Цена книги «The Pragmatic Programmer» ранее отсутствовала в словаре, но теперь она добавлена.

Для удаления элемента из словаря можно использовать метод popitem() или pop().

def main():
    programming_books = {
        'C Programming Language': 35,
        'Introduction to Algorithms': 100,
        'Clean Code: A Handbook of Agile Software Craftsmanship': 50
    }

    print(programming_books.popitem())

    key = 'C Programming Language'

    print(programming_books.pop(key))

    print(programming_books)


if __name__ == '__main__':
    main()

# ('Clean Code: A Handbook of Agile Software Craftsmanship', 50)
# 35
# {'Introduction to Algorithms': 100}

Метод popitem() удаляет последний элемент в словаре и возвращает его в виде кортежа. Метод pop() возвращает значение для заданного ключа и удаляет эту пару.

Последний вызов функции print() показывает, что действительно две пары были удалены из словаря в результате вызовов pop().

И, наконец, есть метод clear(), который удаляет все пары в заданном словаре за один раз.

def main():
    programming_books = {
        'C Programming Language': 35,
        'Introduction to Algorithms': 100,
        'Clean Code: A Handbook of Agile Software Craftsmanship': 50
    }

    programming_books.clear()

    print(programming_books)


if __name__ == '__main__':
    main()

# {}

Методы словарей

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

Здесь-то и пригодятся методы объектов типа dict.

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

def main():
    programming_books = {
        'C Programming Language': 35,
        'Introduction to Algorithms': 100,
        'Clean Code: A Handbook of Agile Software Craftsmanship': 50
    }

    for key in programming_books.keys():
        print(key)


if __name__ == '__main__':
    main()

# C Programming Language
# Introduction to Algorithms
# Clean Code: A Handbook of Agile Software Craftsmanship

Подобно методу keys(), существует метод values(), который возвращает все значения в словаре.

def main():
    programming_books = {
        'C Programming Language': 35,
        'Introduction to Algorithms': 100,
        'Clean Code: A Handbook of Agile Software Craftsmanship': 50
    }

    for value in programming_books.values():
        print(value)


if __name__ == '__main__':
    main()

# 35
# 100
# 50

Наконец, если вам нужны и ключи, и значения в виде кортежей, вы можете использовать метод items().

def main():
    programming_books = {
        'C Programming Language': 35,
        'Introduction to Algorithms': 100,
        'Clean Code: A Handbook of Agile Software Craftsmanship': 50
    }

    for item in programming_books.items():
        print(item)


if __name__ == '__main__':
    main()

# ('C Programming Language', 35)
# ('Introduction to Algorithms', 100)
# ('Clean Code: A Handbook of Agile Software Craftsmanship', 50)

Как писать функции в Python

Функция в Python — это блок кода, который выполняет определенную задачу или определенные операции. Она может принимать входные данные (аргументы), обрабатывать их и возвращать результат. Функции используются для организации кода, делая его более структурированным, читаемым и многократно используемым.

def print_hello():
    print('Hello, World!')


def main():
    print_hello()


if __name__ == '__main__':
    main()

# Hello, World!

Функция создается и определяется с использованием ключевого слова def, за которым следует имя функции и список параметров в круглых скобках.

В данном примере программа print_hello() выводит Hello, World! в терминале. Она не принимает никаких аргументов.

def print_hello(message):
    print(message)


def main():
    print_hello('Hello, Universe!')


if __name__ == '__main__':
    main()

# Hello, Universe!

Чтобы не выводить постоянно сообщение Hello, World!, можно передать функции текст, который она должна вывести.

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

def print_hello(message, is_lower=False):
    if is_lower:
        print(message.lower())
    else:
        print(message.upper())


def main():
    print_hello('Hello, Universe!')
    print_hello('Hello, Universe!', True)


if __name__ == '__main__':
    main()

# HELLO, UNIVERSE!
# hello, universe!

Установка значения по умолчанию для аргумента функции делает его необязательным. Таким образом, если при вызове функции не передать значение is_lower, то программа будет использовать значение по умолчанию (is_lower=False).

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

def hello(message, is_lower=False):
    if is_lower:
        return message.lower()
    else:
        return message.upper()


def main():
    print(hello('Hello, Universe!'))
    print(hello('Hello, Universe!', True))


if __name__ == '__main__':
    main()

# HELLO, UNIVERSE!
# hello, universe!

Поскольку функция больше не распечатывает сообщение, лучше изменить ее название с print_hello() на просто hello().

Вызов функции возвращает строку, которую можно распечатать в функции main().

Вы также можете сохранять результаты функции в переменных, а не передавать их в функцию print()  напрямую.

def hello(message, is_lower=False):
    if is_lower:
        return message.lower()
    else:
        return message.upper()


def main():
    uppercase_message = hello('Hello, Universe!')
    print(uppercase_message)

    lowercase_message = hello('Hello, Universe!', True)
    print(lowercase_message)


if __name__ == '__main__':
    main()

# HELLO, UNIVERSE!
# hello, universe!

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

def total(numbers):
    s = 0
    for number in numbers:
        s += number
    return s


def main():
    print(total([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))


if __name__ == '__main__':
    main()

# 55

В эту функцию можно передать список чисел и получить их сумму. Мне пришлось назвать функцию total() вместо sum(), потому что существует встроенная функция с таким названием.

Есть еще одно понятие, связанное с функциями, которое я хотел бы обсудить в этом разделе, — рекурсия.

Рекурсия в Python или программировании в целом — это техника, позволяющая заставить функцию вызывать саму себя для итеративного выполнения задачи.

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

def natural_sum(last_number):
    if last_number < 1:
        return last_number

    total = 0
    for number in range(1, last_number + 1):
        total += number

    return total


def main():
    last_number = int(input('up to which number would you like to calculate the sum?\n- '))

    print(natural_sum(last_number))


if __name__ == '__main__':
    main()

# up to which number would you like to calculate the sum?
# - 10
# 55

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

Теперь давайте попробуем написать ту же программу, но без цикла.

def recursive_natural_sum(last_number):
    if last_number < 1:
        return last_number

    return last_number + recursive_natural_sum(last_number - 1)


def main():
    last_number = int(input('up to which number would you like to calculate the sum?\n- '))

    print(recursive_natural_sum(last_number))


if __name__ == '__main__':
    main()

# up to which number would you like to calculate the sum?
# - 10
# 55

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

При первом вызове функции recursive_natural_sum() со значением 10 запускается своеобразная цепная реакция.

Поскольку значение не меньше 1, оператор if оценивается в False и вызывается второй оператор return.

Внутри этого оператора return вы вызываете функцию recursive_natural_sum(), передавая ей значение last_number - 1, которое в данный момент равно 9.

Вы также добавляете возвращаемое значение из этого вызова к текущему значению переменной last_number.

Но возвращаемого значения вы не получите, так как внутренний вызов функции вызовет себя снова с last_number - 1, которое в этот момент будет равно 8.

Схема стека вызовов

Вызов продолжается до тех пор, пока значение last_digit не станет равным нулю. Как только оно становится равным нулю, оператор if оценивается как True и вызовы функций начинают возвращать значение.

Схема возвратов

Значение, возвращаемое при каждом вызове функции, равно last_number + (last_number - 1). К концу цепочки рекурсии оно складывается в 55.

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

Лямбда-функции

Анонимные функции или лямбда-функции — это функции без имени. Это не является чем-то исключительным для Python: большинство современных языков программирования имеют ту или иную реализацию лямбда-функций.

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

print_hello = lambda: print('Hello, World!')


def main():
    print_hello()


if __name__ == '__main__':
    main()

# Hello, World!

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

Лямбда-функции полезны, когда требуется передать функцию в качестве аргумента для вызова другой функции. Возьмем, к примеру, функцию filter().

def check_even(number):
    if number % 2 == 0:
        return True
    else:
        return False


def main():
    numbers = [1, 2, 5, 4, 7, 88, 12, 15, 55, 77, 95]

    even_numbers = filter(check_even, numbers)

    print(list(even_numbers))


if __name__ == '__main__':
    main()

# [2, 4, 88, 12]

Функция filter() принимает в качестве двух аргументов функцию и итерируемый объект. Функция должна описывать логику фильтрации, а итерируемый объект будет содержать значения, для которых необходимо произвести фильтрацию.

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

Функция check_even() принимает в качестве аргумента число. Она возвращает True, если число делится на два, и False, если нет.

Функция filter() выполняет итерацию по списку чисел и передает каждое число в функцию check_even().

Она сохраняет число, если функция check_even() возвращает True, или отбрасывает число, если функция check_even() возвращает False.

Теперь давайте попробуем избавиться от check_even() и воспользоваться лямбда-функцией прямо в вызове метода filter().

def main():
    numbers = [1, 2, 5, 4, 7, 88, 12, 15, 55, 77, 95]

    even_numbers = filter(lambda number: True if number % 2 == 0 else False, numbers)

    print(list(even_numbers))


if __name__ == '__main__':
    main()

# [2, 4, 88, 12]

Эта лямбда принимает аргумент с именем number и возвращает True, если он делится на два, и False в противном случае.

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

Таким образом, True if number % 2 == 0 else False эквивалентно return True if number % 2 == 0 else False. Оператор if...else внутри лямбды имеет краткую форму.

Область видимости в Python

Область видимости (scope) в Python определяет, где в программе можно использовать определенную переменную или объект.

def outside():
    message = 'Hello, World!'


def main():
    print(message)


if __name__ == '__main__':
    main()

# NameError: name 'msg' is not defined

В данном примере переменная message определена внутри функции outside()  и больше нигде не существует.

В результате при попытке обратиться к этой переменной из функции main() возникает NameError, так как переменная видна только внутри outside().

Такие переменные называются локальными и существуют только в пределах блока, в котором они были объявлены.

Глобальные переменные обычно объявляются вне какого-либо конкретного блока кода.

message = 'Hello, World!'


def main():
    print(message)


if __name__ == '__main__':
    main()

# Hello, World!

Как видите, теперь переменная message не имеет отступов и объявлена в верхней части функции. Можно было объявить переменную после функции main().

def main():
    print(message)


message = 'Hello, World!'

if __name__ == '__main__':
    main()

# Hello, World!

Это работает потому, что обращение к переменной происходит только после вызова функции main() внутри блока if.

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

message = 'Hello, {name}!'


def main():
    message = message.format(name='Farhan')
    print(message)


if __name__ == '__main__':
    main()
    
# UnboundLocalError: local variable 'message' referenced before assignment

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

Но если вы попытаетесь выполнить этот код, вы получите ошибку «локальная переменная ‘message’ используется до присвоения сообщения». Проще говоря, вы пытаетесь обратиться к локальной переменной с именем message прежде, чем вообще что-то присвоить ей.

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

message = 'Hello, {name}!'


def main():
    message = str()
    
    message = message.format(name='Farhan')
    print(message)


if __name__ == '__main__':
    main()

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

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

message = 'Hello, {name}!'


def main():
    global message

    message = message.format(name='Farhan')
    print(message)


if __name__ == '__main__':
    main()

# Hello, Farhan!

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

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

def greet(name):
    message = 'Hello, {name}!'

    def include_name():
        message = message.format(name=name)

    include_name()
    return message


def main():
    print(greet('Farhan'))


if __name__ == '__main__':
    main()

# UnboundLocalError: local variable 'message' referenced before assignment

В данном примере мы имеем дело с тремя функциями. Есть функция main(), есть функция greet(), а внутри нее находится функция include_name().

Функция greet() принимает в качестве аргумента имя, но не сразу включает его в сообщение.

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

Видите ли, переменная message находится вне области видимости функции  include_message(), и поэтому вы получаете сообщение об ошибке «referenced before assignment».

def greet(name):
    message = 'Hello, {name}!'

    def include_name():
        global message
        
        message = message.format(name=name)

    include_name()
    return message


def main():
    print(greet('Farhan'))


if __name__ == '__main__':
    main()

# NameError: name 'message' is not defined

Использовать ключевое слово global также нельзя, поскольку переменная message не определена в глобальной области видимости, что и диктует сообщение об ошибке.

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

def greet(name):
    message = 'Hello, {name}!'

    def include_name():
        nonlocal message
        message = message.format(name=name)

    include_name()
    return message


def main():
    print(greet('Farhan'))


if __name__ == '__main__':
    main()

# Hello, Farhan!

Теперь функция include_name() будет искать переменную message в области видимости функции greet(), а не в своей локальной области видимости.

Передача аргументов в функцию с помощью *args и **kwargs

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

Конечно, числа можно передавать в виде кортежа или списка, но, возможно, вы захотите передать их в виде обычных аргументов, разделенных запятыми. Для этого можно использовать *args или неименованные аргументы в Python.

def total(*args):
    print(type(args))

    t = 0
    for arg in args:
        t += arg

    return t


def main():
    print(total(1, 2, 3, 4, 5))


if __name__ == '__main__':
    main()

# <class 'tuple'>
# 15

Здесь в качестве аргумента в функцию total() можно передать произвольное количество переменных, и внутри функции они будут доступны в виде кортежа.

Не обязательно называть аргумент как *args можно назвать его как-нибудь более описательно, например*numbers или как-нибудь еще. Главное, чтобы перед ним стояла звездочка.

Еще есть именованные аргументы, **kwargs. Они позволят вам получить доступ к аргументам функции в виде словаря.

def items(**kwargs):
    print(type(kwargs))

    for key, value in kwargs.items():
        print(f"{key} : {value}")


def main():
    items(
        Apple=10,
        Orange=8,
        Grape=35
    )


if __name__ == '__main__':
    main()

# <class 'dict'>
# Apple : 10
# Orange : 8
# Grape : 35

В этом случае можно передавать произвольное количество пар ключ-значение и обращаться к ним как к словарю внутри функции items().

Использовать слово **kwargs, опять же, не обязательно. Название может быть любым.

Метод items() внутри словарей позволяет выполнять итерации по ним.

Также можно изменить слова «key» и «value». Более читабельный вариант функции может выглядеть следующим образом:

def items(**fruits):
    print(type(fruits))

    for fruit, price in fruits.items():
        print(f"{fruit} : {price}")


def main():
    items(
        Apple=10,
        Orange=8,
        Grape=35
    )


if __name__ == '__main__':
    main()

# <class 'dict'>
# Apple : 10
# Orange : 8
# Grape : 35

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

Что такое модули в Python?

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

Например, предположим, что у вас есть проект на языке Python с двумя файлами. Первый из них может быть «mathstuff.py», а второй — «main.py».

Файл «mathstuff.py» может содержать материалы, связанные с математикой, например, функцию, которая суммирует все натуральные числа в диапазоне.

# mathstuff.py

def natural_sum(last_number):
    if last_number < 1:
        return last_number

    total = 0
    for number in range(1, last_number + 1):
        total += number

    return total

Теперь вы можете импортировать эту функцию в любой другой файл, например, в файл «main.py».

import mathstuff


def main():
    last_number = int(input('up to which number would you like to calculate the sum?\n- '))

    print(mathstuff.natural_sum(last_number))


if __name__ == '__main__':
    main()

# up to which number would you like to calculate the sum?
# - 10
# 55

Оператор import, как следует из названия, импортирует фрагменты кода из другого файла или модуля.

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

В таких ситуациях можно использовать оператор from...import.

from mathstuff import natural_sum


def main():
    last_number = int(input('up to which number would you like to calculate the sum?\n- '))

    print(natural_sum(last_number))


if __name__ == '__main__':
    main()

# up to which number would you like to calculate the sum?
# - 10
# 55

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

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

import mathstuff as math


def main():
    last_number = int(input('up to which number would you like to calculate the sum?\n- '))

    print(math.natural_sum(last_number))


if __name__ == '__main__':
    main()

# up to which number would you like to calculate the sum?
# - 10
# 55

Также работает с оператором from...import.

from mathstuff import natural_sum as nsum


def main():
    last_number = int(input('up to which number would you like to calculate the sum?\n- '))

    print(nsum(last_number))


if __name__ == '__main__':
    main()

# up to which number would you like to calculate the sum?
# - 10
# 55

Импорт модулей — это то, что вам придется делать постоянно. Кроме модулей, существуют также пакеты.

В этих примерах оба файлы находятся в одной и той же папке. Пакеты — это удобный способ хранения связанных модулей Python в разных папках.

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

Этот пакет framework может иметь несколько подпакетов. Например, может существовать пакет http для обработки HTTP-запросов и ответов.

├───framework
│   └───http

На данный момент это всего лишь обычные папки. Чтобы превратить их в Python-пакеты, вам нужно всего лишь создать внутри них файлы "__init__.py".

├───framework
│   │   __init__.py
│   │
│   └───http
│           __init__.py

Теперь эти папки превратились в пакеты. Файлы «__init__.py» будут сообщать системе импорта Python, что эти папки действительно являются пакетами.

Наконец, чтобы разместить некоторый код внутри пакета http, создайте файл с именем response.py со следующим содержанием:

# framework/http/response.py

from json import dumps


def as_json(message):
    return dumps({
        'message': message
    })

Во-первых, вы импортируете функцию dumps  из пакета json. Они являются частью стандартной библиотеки Python.

Функция dumps может превратить объект Python, например словарь, в строку JSON, то есть функция as_json() возвращает заданное значение в формате JSON.

{"message": "Hello, World"}

Теперь вы можете импортировать эту функцию в файл «main.py».

from framework.http.response import as_json


def main():
    print(as_json('Hello, World!'))


if __name__ == '__main__':
    main()

# {"message": "Hello, World"}

Вместо того чтобы импортировать функцию as_json()  в другой файл Python, можно просто импортировать ее в файл «framework/http/__init__.py».

Затем можно обновить файл «main.py», чтобы он использовал обновленный путь к пакету.

from framework.http import as_json


def main():
    print(as_json('Hello, World!'))


if __name__ == '__main__':
    main()

# {"message": "Hello, World"}

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

Как эффективно использовать документацию по Python

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

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

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

Первый шаг — посетить https://docs.python.org/ и вы автоматически попадете на страницу с документацией по последней версии Python.

Документация по Python (https://docs.python.org/)

На момент написания статьи последней версией Python является 3.11.4, однако на моих компьютерах по-прежнему установлена версия 3.10.11.

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

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

Я расскажу о трех ссылках с этой страницы, которые мне очень помогли. Первая — «The Python Tutorial».

Самоучитель Python (https://docs.python.org/3/tutorial/index.html)

Когда я переходил с языка C на Python, я изучал именно этот учебник. Начинается он со знакомства с интерпретатором Python.

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

Другая чрезвычайно полезная страница — «Глоссарий». Она содержит список всей важной терминологии, с которой вы можете столкнуться при работе с Python.

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

Наконец, страница «The Python Standard Library» представляет собой подробное описание всего, что входит в стандартную библиотеку Python.

Справка по библиотеке (https://docs.python.org/3/library/index.html)

Например, я хочу узнать о типе менеджера контекста (что выходит за рамки данной книги). Я могу просто заглянуть в раздел «Встроенные типы».

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

JSON находится в разделе «Работа с данными в Интернете»

Перейдя по ссылке, вы попадете на страницу, описывающую работу пакета JSON.

Кодировщик и декодировщик JSON (https://docs.python.org/3/library/json.html)

Страница содержит не только текст, но и практические и очень полезные примеры кода.

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

Заключение

От всего сердца благодарю вас за время, потраченное на чтение этой статьи.