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

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

1. Фундамент: установка, типы данных, переменные и операции

Фундамент: установка, типы данных, переменные и операции

Зачем нужен этот фундамент

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

К концу статьи вы сможете:

  • Установить Python и проверить, что он работает
  • Запускать простые программы
  • Понимать, что такое типы данных int, float, bool, str
  • Создавать переменные и менять их значения
  • Использовать арифметические, сравнительные и логические операции
  • !Схема помогает понять, что код выполняет интерпретатор, построчно и последовательно

    Установка и настройка

    Что именно нужно установить

    Вам нужны две вещи:

  • Python (интерпретатор) — программа, которая выполняет ваш код
  • Среда разработки — удобный редактор, например VS Code
  • Установка Python

  • Скачайте установщик с официального сайта: Python Downloads
  • Установите Python
  • На Windows важно включить опцию добавления Python в PATH (обычно это галочка Add Python to PATH)
  • Проверка установки в терминале (командной строке):

    Если команда не сработала, попробуйте:

    Вы должны увидеть версию, например Python 3.12.x.

    Установка VS Code

  • Установите редактор: Visual Studio Code
  • Поставьте расширение Python в VS Code (обычно оно называется Python и публикуется Microsoft)
  • Как запускать Python

    Есть два базовых способа.

  • Интерактивный режим (быстро проверять идеи):
  • Вы увидите приглашение >>>. Можно вводить команды и сразу получать результат:

    Чтобы выйти:

  • Запуск файла (настоящие программы):
  • Создайте файл main.py с таким кодом:

    Запустите:

    Что такое данные и типы данных

    Данные — это то, с чем работает программа: числа, текст, ответы да/нет и так далее.

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

    В этой статье мы берём четыре базовых типа.

    Целые числа: int

    int — целые числа без дробной части.

    Примеры:

    Дробные числа: float

    float — числа с дробной частью.

    Примеры:

    Важно: float хранится приближённо, поэтому иногда возможны неожиданные эффекты:

    Это не ошибка Python, а особенность представления дробных чисел в компьютере.

    Логический тип: bool

    bool — значения истинности.

  • True — истина
  • False — ложь
  • Пример:

    Строки: str

    str — текст.

    Примеры:

    Строки можно складывать (склеивать):

    Переменные и присваивание

    Переменная — это имя, которое ссылается на значение.

    Присваивание — запись значения в переменную с помощью =.

    Пример:

    Здесь важны две идеи:

  • = в Python — это не “равно” из математики, а команда “сохрани справа в переменную слева”
  • программа выполняется последовательно: сначала создаётся age = 20, потом выполняется увеличение
  • Имена переменных

    Хорошие правила:

  • используйте понятные имена: total_price, user_name
  • стиль Python: snake_case (слова через подчёркивание)
  • нельзя начинать имя с цифры и использовать пробелы
  • Пример корректных имён:

    Операции: что можно делать с данными

    Арифметика (в основном для int и float)

    | Операция | Пример | Смысл | |---|---|---| | + | 2 + 3 | сложение | | - | 5 - 1 | вычитание | | | 4 2 | умножение | | / | 5 / 2 | деление (почти всегда даёт float) | | // | 5 // 2 | целочисленное деление | | % | 5 % 2 | остаток от деления | | | 2 3 | степень |

    Примеры:

    Сравнение (даёт bool)

    Операции сравнения возвращают True или False.

    | Операция | Пример | Смысл | |---|---|---| | == | a == b | равно | | != | a != b | не равно | | < | a < b | меньше | | <= | a <= b | меньше или равно | | > | a > b | больше | | >= | a >= b | больше или равно |

    Пример:

    Логические операции (для bool)

    | Операция | Пример | Смысл | |---|---|---| | and | a and b | истина, если оба истинны | | or | a or b | истина, если хотя бы один истинен | | not | not a | отрицание |

    Пример:

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

    Самые базовые:

  • + склеивает строки
  • * повторяет строку заданное число раз
  • Функция print() и чтение кода

    print() выводит значения на экран.

    Обратите внимание:

  • запятая в print() выводит значения через пробел
  • строки берутся в кавычки
  • Приведение типов: когда данные нужно “перевести”

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

    Примеры:

    Важно понимать:

  • int("3.5") вызовет ошибку, потому что строка не является целым числом
  • bool("False") будет True, потому что непустая строка считается истинной; строка не “понимает смысл” слова False
  • Типичные ошибки новичков

  • Путать = и ==
  • Складывать строку и число без преобразования
  • Ожидать, что / даст целое число
  • Небольшой ориентир по “философии” Python

    > “Beautiful is better than ugly.” — Tim Peters, The Zen of Python (PEP 20)

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

    Итоги и что дальше

    В этой статье вы:

  • установили Python и среду разработки
  • разобрали базовые типы данных: int, float, bool, str
  • научились создавать переменные и выполнять операции
  • Дальше мы перейдём к управлению выполнением программы: условиям if и циклам while и for. Это превратит набор команд в полноценные алгоритмы, которые умеют принимать решения и повторять действия.

    2. Управление потоком: ветвления и циклы while/for

    Управление потоком: ветвления и циклы while/for

    Зачем нужно управление потоком

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

    Но реальная программа почти всегда должна уметь:

  • принимать решения (в зависимости от условий)
  • повторять действия (несколько раз или пока условие истинно)
  • Для этого в Python есть конструкции управления потоком: ветвления if и циклы while/for. Это основа алгоритмов: теперь ваш код сможет вести себя по-разному в разных ситуациях.

    !Схема показывает, как программа выбирает одну из веток и продолжает выполнение

    Блоки кода и отступы

    В Python блоки кода задаются отступами, а не фигурными скобками.

    Правило простое:

  • после if, elif, else, while, for ставится двоеточие :
  • следующая строка (и все строки блока) идут с отступом (обычно 4 пробела)
  • Пример корректного блока:

    Если убрать отступ, Python не поймёт, где тело условия или цикла, и выдаст ошибку.

    Ветвление if: как принимать решения

    Простейшее условие

    if выполняет блок кода, если условие истинно (True).

    Условие — это выражение, которое возвращает bool (True или False). В прошлой статье вы уже видели операции сравнения (<, >=, ==) и логические операции (and, or, not) — теперь они становятся особенно полезными.

    if и else

    Если нужно выполнить один блок при истинном условии и другой — при ложном, используют else.

    if, elif, else: несколько вариантов

    Если вариантов больше двух, используйте elif (это “иначе если”).

    Как это работает:

  • Python проверяет условия сверху вниз
  • как только нашлось истинное, выполняется его блок
  • остальные ветки пропускаются
  • Логические условия: and, or, not

    Иногда проверка состоит из нескольких частей.

    Пример с and (оба условия должны быть истинны):

    Пример с or (достаточно одного истинного):

    Пример с not (инверсия):

    Что считается True и False без сравнения

    Иногда в if можно писать не сравнение, а само значение. Python преобразует его к логическому виду.

    Частые правила:

  • 0 и 0.0 считаются False
  • пустая строка "" считается False
  • непустая строка, любое ненулевое число считаются True
  • Пример:

    Важно: это не “магия”, а обычное приведение к bool по правилам языка.

    Цикл while: повторять, пока условие истинно

    while повторяет блок кода, пока условие истинно.

    Пример: счётчик

    Разбор:

  • условие проверяется перед каждой итерацией
  • если условие False, цикл завершается
  • если забыть изменить count, цикл может стать бесконечным
  • !Схема показывает, что while всегда возвращается к проверке условия

    break и continue: управление внутри цикла

    Иногда нужно изменить поведение цикла внутри:

  • break — досрочно завершает цикл
  • continue — пропускает остаток тела цикла и переходит к следующей итерации
  • Пример break:

    Этот код выведет 1, 2, 3 и остановится.

    Пример continue:

    Этот код выведет 1, 2, 4, 5 (число 3 пропустится).

    Цикл for: повторять для каждого элемента последовательности

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

    На старте курса мы чаще всего используем for вместе с range().

    range(): как получить последовательность чисел

    range() создаёт последовательность целых чисел.

    1) Если указать один аргумент range(stop), числа идут от 0 до stop - 1:

    Вывод будет: 0 1 2 3 4.

    2) Если указать два аргумента range(start, stop), числа идут от start до stop - 1:

    Вывод будет: 2 3 4 5.

    3) Если указать три аргумента range(start, stop, step), можно задать шаг:

    Вывод будет: 10 8 6 4 2.

    Ключевая деталь: stop никогда не включается.

    Пример: сумма чисел

    Этот код суммирует числа от 1 до 5.

    for по строке

    Строка — это последовательность символов, по ней тоже можно пройти циклом for.

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

    Как выбрать: while или for

    Ориентируйтесь на смысл задачи:

  • for — когда известно, по чему вы идёте (например, по диапазону чисел или по символам строки)
  • while — когда неизвестно заранее, сколько раз нужно повторить, и остановка зависит от условия
  • Примеры:

  • “повторить 10 раз” — обычно for
  • “повторять, пока пользователь не введёт правильный пароль” — обычно while
  • Типичные ошибки новичков

  • Забыть двоеточие : после if/while/for
  • Сделать неправильный отступ в теле блока
  • Перепутать == (сравнение) и = (присваивание)
  • Получить бесконечный while, забыв изменить переменные, влияющие на условие
  • Ожидать, что range(5) даст числа от 1 до 5 (на самом деле от 0 до 4)
  • Итоги и что дальше

    Теперь вы умеете:

  • строить ветвления с if, elif, else
  • собирать сложные условия с and, or, not
  • повторять действия с помощью while и управлять циклом через break и continue
  • использовать for и range() для повторения заданное число раз
  • Дальше мы перейдём к простым структурам данных: спискам, кортежам и более подробной работе со строками. Именно на коллекциях циклы for раскрываются по-настоящему, потому что позволяют обрабатывать наборы данных.

    3. Коллекции-1: списки, кортежи, строки и базовая обработка

    Коллекции-1: списки, кортежи, строки и базовая обработка

    Зачем нужны коллекции

    В прошлых статьях вы научились работать с типами int, float, bool, str, переменными и управлением потоком (if, while, for). Следующий шаг — научиться хранить несколько значений сразу и обрабатывать их циклом.

    Коллекции — это структуры данных, которые содержат набор элементов. На этом уровне нам важны три базовые коллекции:

  • Список (list) — упорядоченная изменяемая коллекция
  • Кортеж (tuple) — упорядоченная неизменяемая коллекция
  • Строка (str) — текст, который ведёт себя как неизменяемая последовательность символов
  • Когда вы умеете хранить данные в коллекциях, циклы for начинают работать “по-настоящему”: вы можете обрабатывать наборы данных, а не отдельные переменные.

    !Наглядно показывает индексацию и идею изменяемости/неизменяемости

    Общие идеи для list, tuple и str

    Порядок и индексы

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

  • Индексация начинается с 0
  • Доступ к элементу: name[index]
  • Отрицательные индексы идут с конца: -1 — последний элемент
  • Примеры:

    Длина коллекции

    Функция len() возвращает количество элементов.

    Проверка “содержится ли элемент”

    Оператор in проверяет наличие элемента.

    Срезы (slicing)

    Срез — это “взять кусочек” последовательности.

  • seq[start:stop] берёт элементы от start до stop, не включая stop
  • Можно опускать границы: seq[:stop], seq[start:]
  • Подробно про структуры данных в учебнике Python: Data Structures

    Списки (list): изменяемая коллекция

    Создание списка

    Список создаётся квадратными скобками [].

    Изменение элементов

    Главная особенность списка — его можно менять.

    Частые операции со списками

  • append(x) добавляет элемент в конец
  • extend(iterable) добавляет элементы из другой последовательности
  • insert(index, x) вставляет элемент по индексу
  • pop() удаляет и возвращает последний элемент (или pop(index))
  • remove(x) удаляет первое вхождение элемента x
  • sort() сортирует список на месте
  • reverse() разворачивает список на месте
  • Примеры:

    Важное про присваивание списков

    Если сделать b = a, то это не копия списка, а вторая ссылка на тот же список.

    Если нужна копия (на старте курса достаточно простого варианта):

    Кортежи (tuple): неизменяемая коллекция

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

    Создание кортежа

    Нельзя менять элементы

    Распаковка кортежа

    Кортежи часто используют для “пары/тройки значений”, которые удобно разложить по переменным.

    Документация: Built-in Types — tuple

    Строки (str) подробнее: последовательность символов

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

    Индексация и срезы работают как у коллекций

    Строки неизменяемые

    Строку нельзя “поправить на месте”. Любая операция “изменения” создаёт новую строку.

    Полезные методы строк

  • lower() и upper() меняют регистр
  • strip() убирает пробелы по краям
  • replace(old, new) заменяет подстроку
  • split(sep) разбивает строку на список
  • join(list_of_strings) склеивает список строк
  • find(sub) ищет подстроку и возвращает индекс или -1
  • startswith(prefix) и endswith(suffix) проверяют начало/конец
  • Примеры:

    Документация: Built-in Types — str

    Базовая обработка коллекций циклами

    Проход по элементам: самый частый стиль

    Если вам не нужны индексы, проходите сразу по элементам.

    То же самое для строк:

    Проход по индексам: когда нужен номер позиции

    Иногда важно знать индекс (например, чтобы изменить список).

    Вариант с range(len(...)):

    Более читаемый вариант — enumerate(), он даёт пару (индекс, элемент):

    Документация: Built-in Functions — enumerate

    Накопление результата: сумма, счётчик, сбор в новый список

    Очень частый шаблон: завести переменную-накопитель и обновлять её в цикле.

    Пример: посчитать сумму элементов списка.

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

    Вложенные циклы: обработка “коллекции коллекций”

    Вложенный for — это цикл внутри цикла. Он нужен, когда данные “двухмерные”: например, список строк или список списков.

    Пример: вывести все символы во всех словах.

    Важно понимать порядок:

  • внешний цикл берёт очередное слово
  • внутренний цикл проходит по символам этого слова
  • Типичные ошибки новичков

  • Пытаться изменить строку по индексу: s[0] = "H" не работает, потому что str неизменяемая.
  • Ожидать, что срез включает правую границу: a[1:3] берёт элементы с индексами 1 и 2.
  • Путать добавление элемента и добавление списка: append([1, 2]) добавит один элемент-список, а extend([1, 2]) добавит два элемента.
  • Делать “копию” списка через b = a и удивляться, что меняются оба.
  • Итоги и что дальше

    Теперь вы умеете:

  • работать со списками (list): создавать, читать, изменять, добавлять и удалять элементы
  • понимать, зачем нужны кортежи (tuple) и чем полезна неизменяемость
  • использовать строки (str) как последовательности символов и применять базовые методы строк
  • обходить коллекции циклом for, включая варианты с индексами и вложенные циклы
  • Дальше мы начнём применять эти навыки как алгоритмы обработки коллекций: поиск минимума/максимума, линейный поиск, фильтрация и преобразование данных.

    4. Алгоритмы для коллекций: агрегирование, поиск и преобразования

    Алгоритмы для коллекций: агрегирование, поиск и преобразования

    Зачем нужны алгоритмы для коллекций

    В прошлой статье вы научились хранить данные в коллекциях (list, tuple, str) и обходить их циклом for. Теперь следующий шаг: научиться решать типовые задачи обработки наборов данных.

    В программировании такие задачи обычно сводятся к трём группам алгоритмов:

  • Агрегирование — получить одно значение из многих (сумму, минимум, максимум, среднее, количество).
  • Поиск — найти элемент (или его позицию), который удовлетворяет условию.
  • Преобразование — построить новую коллекцию на основе старой (например, оставить только чётные числа или преобразовать каждый элемент).
  • Эти алгоритмы — основа для работы с любыми данными: списками оценок, строками, таблицами (позже), логами и так далее.

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

    Универсальный шаблон: один проход по коллекции

    Почти все базовые алгоритмы обработки коллекций делаются так:

  • берём переменные для результата (их часто называют накопителями)
  • проходим по элементам циклом for
  • обновляем результат на каждом шаге
  • Простейший пример: посчитать сумму.

    Ключевая идея: мы не пытаемся “понять список целиком”. Мы обрабатываем элементы по одному и аккуратно накапливаем ответ.

    Агрегирование: сумма, количество, среднее, минимум и максимум

    Сумма и количество

    Часто нужно не только суммировать элементы, но и посчитать, сколько их было (особенно если есть условие).

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

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

    Среднее значение

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

    Почему нужна проверка count == 0: деление на ноль — ошибка.

    Минимум и максимум (вручную)

    Алгоритм поиска минимума устроен так:

  • берём первый элемент как текущий минимум
  • сравниваем каждый следующий элемент с текущим минимумом
  • если нашли меньше — обновляем минимум
  • Аналогично для максимума:

    Важная деталь: этот алгоритм требует, чтобы список был непустым, иначе nums[0] вызовет ошибку.

    Что делать с пустыми списками

    Если список может быть пустым, есть два базовых подхода:

  • заранее проверить len(nums) == 0 и обработать отдельно
  • договориться, что пустой список в вашей задаче невозможен
  • Пример с проверкой:

    Встроенные функции (полезно знать)

    Python умеет делать часть агрегирования готовыми функциями:

  • sum(nums)
  • min(nums)
  • max(nums)
  • len(nums)
  • Но в этом курсе важно понимать как это устроено, потому что дальше вы будете агрегировать не только числа (например, искать минимальную цену среди товаров, где у каждого товара несколько полей).

    Документация:

  • Built-in Functions — sum
  • Built-in Functions — min
  • Built-in Functions — max
  • Поиск: линейный поиск

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

    Он называется линейным, потому что в худшем случае придётся проверить все элементы списка (от начала до конца).

    Найти: существует ли элемент

    Пример: проверить, есть ли число 7 в списке.

    Здесь:

  • found — переменная-флаг (логическая переменная)
  • break завершает цикл сразу, как только элемент найден
  • Найти индекс первого вхождения

    Иногда нужно не просто найти значение, а узнать, где оно находится.

    Почему index начинается с -1: это удобный “сигнал”, что элемент не найден.

    Поиск по строке

    Строка — тоже последовательность, и линейный поиск по ней работает так же.

    Пример: есть ли в слове цифра.

    Преобразования: создать новый список на основе старого

    Преобразование обычно означает одно из двух:

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

    Фильтрация

    Пример: оставить только чётные числа.

    Шаблон фильтрации:

  • создать пустой список
  • пройти по исходному
  • добавлять (append) только подходящие элементы
  • Преобразование каждого элемента

    Пример: построить новый список квадратов.

    Комбинация: сначала фильтрация, потом преобразование

    Пример: из списка чисел взять только положительные и сделать их в 10 раз больше.

    Преобразование строк

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

    Документация по строковым методам:

  • Built-in Types — str
  • Частые ошибки и как их избегать

  • Неправильная инициализация минимума/максимума
  • Если вы сделаете min_value = 0, то для списка из отрицательных чисел минимум будет найден неверно. Надёжнее начинать с nums[0] (при условии, что список непуст).

  • Забыли про пустой список
  • Если используете nums[0], заранее решите, что делать при len(nums) == 0.

  • Ищете элемент, но не останавливаетесь
  • Если нужно первое вхождение, используйте break, иначе вы можете случайно получить последнее вхождение (или просто сделать лишнюю работу).

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

    Итоги и что дальше

    Теперь вы умеете строить базовые алгоритмы обработки коллекций:

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

    5. Коллекции-2: словари и множества для отображения и уникальности

    Коллекции-2: словари и множества для отображения и уникальности

    Зачем нужны словари и множества

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

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

    Для таких задач в Python есть две очень важные структуры данных:

  • Словарь (dict) — хранит пары ключ → значение и позволяет быстро находить значение по ключу.
  • Множество (set) — хранит только уникальные элементы и позволяет быстро проверять, встречался ли элемент.
  • !Схема сравнивает идею отображения (dict) и уникальности (set)

    Словарь (dict): ключи и значения

    Что такое словарь

    Словарь — это коллекция пар ключ → значение.

  • Ключ — то, по чему вы ищете (например, строка "login" или число 42).
  • Значение — то, что вы храните (например, возраст, цена, статус).
  • В отличие от списка, где доступ идёт по индексам 0, 1, 2, ..., в словаре доступ идёт по ключу.

    Документация: Встроенные типы — dict

    Создание словаря

    Пустой словарь:

    Словарь с данными:

    Получение значения по ключу

    Доступ по ключу через []:

    Важно: если ключа нет, будет ошибка KeyError.

    Чтобы безопасно получать значение, используйте get():

    Добавление и изменение

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

    Проверка наличия ключа

    Оператор in для словаря проверяет ключи:

    Основные методы словаря

    | Что нужно сделать | Как сделать | |---|---| | Получить значение безопасно | d.get(key, default) | | Получить все ключи | d.keys() | | Получить все значения | d.values() | | Получить пары (ключ, значение) | d.items() | | Удалить и вернуть значение | d.pop(key) | | Объединить/добавить пары из другого словаря | d.update(other) |

    Пример items():

    Как обходить словарь циклом for

    Три частых варианта.

    По ключам:

    По значениям:

    По парам:

    Ключи должны быть “неизменяемыми”

    Ключ в словаре должен быть таким объектом, который не меняется “на месте”. На практике на старте курса используйте:

  • str
  • int
  • bool
  • tuple (если внутри тоже неизменяемые значения)
  • Например, список (list) нельзя использовать как ключ:

    Типовые задачи для dict

    Хранение данных “по имени”

    Список пользователей в виде словаря “логин → возраст”:

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

    Частотный словарь: посчитать, сколько раз встречается элемент

    Это очень важный мостик от темы “алгоритмы для коллекций” к словарям.

    Задача: посчитать, сколько раз встречается каждое слово.

    Что здесь происходит:

  • counts хранит “слово → сколько раз встретилось”.
  • В цикле мы обновляем значение по ключу.
  • Этот же приём работает для символов строки:

    Множество (set): уникальные элементы

    Что такое множество

    Множество — это коллекция, где:

  • элементы не повторяются
  • порядок элементов не важен
  • удобно проверять принадлежность через in
  • Документация: Встроенные типы — set

    Создание множества

    Пустое множество создаётся не через {} (это словарь), а через set():

    Множество с элементами:

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

    Добавление и удаление

    Добавить элемент:

    Удалить элемент:

  • remove(x) — удалит, но если элемента нет, будет ошибка
  • discard(x) — удалит, а если элемента нет, просто ничего не сделает
  • Проверка принадлежности

    Операции над множествами

    Множества сильны тем, что позволяют легко делать операции “как в логике”.

    | Операция | Смысл | Пример | |---|---|---| | Объединение | элементы из обоих множеств | a | b | | Пересечение | элементы, общие для обоих | a & b | | Разность | элементы из a, которых нет в b | a - b |

    Пример:

    Это полезно в задачах вроде:

  • “какие теги встречаются хотя бы в одном списке” (объединение)
  • “какие пользователи есть в обоих списках” (пересечение)
  • “кто есть в первом списке, но отсутствует во втором” (разность)
  • Как выбрать: list, dict или set

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

  • list, если:
  • - важен порядок - нужны повторы - нужно хранить “просто набор значений”
  • dict, если:
  • - нужно хранить “по имени” или “по ключу” - нужно быстро находить значение по ключу - данные естественно выглядят как “поле → значение” (профиль, настройки)
  • set, если:
  • - важна уникальность - нужно быстро проверять “встречалось ли” - нужны операции объединения/пересечения/разности

    Типичные ошибки новичков

  • Путать {}:
  • - {} — это пустой словарь - set() — это пустое множество
  • Получать значение из словаря по отсутствующему ключу через d[key] и получать KeyError:
  • - если ключ может отсутствовать, используйте get() или проверку if key in d
  • Ожидать порядок в set:
  • - множество не предназначено для “первый/последний элемент”
  • Пытаться использовать list как ключ словаря или как элемент множества:
  • - на старте курса используйте для ключей и элементов множества int, str, tuple

    Итоги и что дальше

    Теперь вы умеете:

  • использовать dict для хранения данных в формате ключ → значение
  • безопасно доставать значения через get() и проверять наличие ключа через in
  • обходить словарь по ключам, значениям и парам (items())
  • использовать set для уникальности и быстрых проверок
  • применять операции множеств: объединение, пересечение, разность
  • Дальше мы начнём активно применять эти структуры в более крупных программах и перейдём к следующей важной теме: функциям и модульности. Функции помогут оформлять повторяющиеся алгоритмы (в том числе для dict и set) в виде понятных, переиспользуемых блоков кода.

    6. Функции и модульность: параметры, возврат, области видимости

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

    Зачем нужны функции

    В прошлых темах вы писали алгоритмы с помощью if, for, while, а также обрабатывали коллекции (list, dict, set). На практике быстро появляется проблема: код разрастается, повторяется, становится сложнее читать и менять.

    Функция — это именованный блок кода, который можно вызвать много раз. Функции помогают:

  • Убирать повторения: один раз написали алгоритм — используете в разных местах.
  • Делать код понятнее: у функции есть имя, которое объясняет смысл.
  • Тестировать частями: проще проверить небольшую функцию, чем целую программу.
  • Собирать программу из модулей: логика разделяется на независимые куски.
  • Часто функцию удобно воспринимать как чёрный ящик:

  • На вход подаются данные (аргументы).
  • Внутри выполняется алгоритм.
  • На выход возвращается результат.
  • !Функция как чёрный ящик: входные данные, обработка, результат и возможные побочные эффекты

    Как определить и вызвать функцию

    Функция определяется с помощью def.

  • def greet(): — заголовок функции (имя и параметры).
  • Тело функции — строки с отступом.
  • greet() — вызов функции.
  • Параметры и аргументы

    Термины:

  • Параметры — переменные в определении функции.
  • Аргументы — конкретные значения при вызове.
  • Пример:

    Несколько параметров

    Позиционные и именованные аргументы

    При вызове можно передавать аргументы:

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

    Значения параметров по умолчанию

    Можно задать значение по умолчанию: тогда при вызове аргумент можно не передавать.

    Возврат значения: return

    return возвращает результат из функции туда, где её вызвали.

    return завершает функцию

    Если в функции встретился return, выполнение тела функции останавливается.

    Если return нет

    Если функция ничего не возвращает явно, она возвращает специальное значение None.

    Это важно: print() выводит на экран, но не является “возвратом результата”.

    Возврат нескольких значений

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

    Функции как способ “упаковать” алгоритм

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

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

    Пример: частотный словарь как функция

    Выгода: теперь вы можете считать частоты в любом месте программы одним вызовом.

    Модульность: как собрать программу из функций

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

    Практичные правила для новичка:

  • Одна функция — одна понятная цель.
  • Имя функции — глагол или действие: find_min, count_words, normalize_name.
  • Лучше вернуть результат (return), чем печатать внутри, если это не “чисто выводящая” функция.
  • Мини-пример структуры

    Здесь:

  • normalize_name() — маленькая “служебная” функция.
  • build_login() — собирает итоговый результат, используя служебную функцию.
  • Области видимости: local и global

    Когда вы вводите переменные, важно понимать: где они существуют и кто имеет к ним доступ.

    Локальная область видимости (внутри функции)

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

    Это полезно: локальные переменные не мешают другим частям программы.

    Глобальная область видимости (снаружи функций)

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

    Почему нельзя “просто так” менять глобальную переменную внутри функции

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

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

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

    Хороший стиль вместо global

    Так проще понимать, откуда берутся изменения.

    Изменяемые объекты и “изменение без global”

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

    Но если вы попытаетесь присвоить items = ... внутри функции, это уже будет новая локальная переменная, и тогда потребуется global.

    Что запомнить

  • def создаёт функцию, () вызывает её.
  • Параметры задаются в определении функции, аргументы передаются при вызове.
  • return возвращает значение и завершает выполнение функции.
  • Если return отсутствует, функция возвращает None.
  • Локальные переменные живут внутри функции.
  • Глобальные переменные можно читать внутри функции, но для присваивания нужен global.
  • Модульность — это привычка строить программу из небольших функций, каждая из которых решает одну задачу.
  • Полезные официальные источники

  • Учебник Python: Определение функций
  • Учебник Python: Области видимости и пространства имён