Модуль 5
Словари и множества: спецификация дрона
3 блок(ов) теории · 10 заданий · 145 баллов
Словарь — это данные под именами: пары «ключ: значение» в фигурных скобках. Спецификация дрона — spec = {"title": "Модуль", "mass_g": 1150, "battery": "LiPo 6S"}: ключ — имя данного, значение — само данное. Значение достают по ключу в квадратных скобках: spec["mass_g"] — это 1150. Ключ может и не найтись: spec["gps"] падает с ошибкой KeyError — прямое чтение требует, чтобы ключ существовал. Для мягкого чтения есть метод get: spec.get("gps", "нет") вернёт "нет", не падая, — второй аргумент и есть запасное значение на случай отсутствия ключа. Значением может быть что угодно, в том числе другой словарь: spec["power"]["cells"] — это два чтения подряд, сначала вложенный словарь-раздел, потом число из него; так в одной спецификации живут вложенные разделы вроде питания. Ключом может быть только неизменяемое значение — строка, число, кортеж; список ключом быть не может (значением — запросто). Ключи в литерале не повторяются: {"alt": 12, "alt": 24} — это {"alt": 24}, поздняя пара молча перезаписывает раннюю. Оператор in отвечает на вопрос «есть ли такой ключ»: "battery" in spec — True, причём in смотрит только ключи, а не значения: "LiPo 6S" in spec — False, хотя такая строка лежит в значениях. Словарь берут, когда у каждого значения есть имя-смысл: спецификация, запись телеметрии. Когда имён нет, а есть просто пронумерованный ряд значений — высоты по секундам, скорости по кругам, — это работа списка из модуля 4.
Перебирают словарь методом items: for name, value in rpm.items() даёт на каждой итерации пару «ключ, значение» — так же, как enumerate давал пару «номер, значение». Частая работа цикла — накопление словаря. Частотный словарь событий бортового журнала — «какое событие сколько раз случилось» — собирают шаблоном counts[e] = counts.get(e, 0) + 1: при первом появлении события get отдаёт дефолт 0, дальше счёт копится. В стандартной библиотеке есть готовый аналог — collections.Counter; здесь собираем руками, полное знакомство с ней — в модуле 9. Вторая работа — слияние. Метод update дописывает в словарь пары другого словаря, перезаписывая совпавшие ключи: после merged.update(override) значение из override главнее. Слияние без побочных эффектов: merged = base.copy() снимает копию, и обновлять можно её; а {**base, **override} собирает новый словарь сразу — две звёздочки «разворачивают» пары обоих словарей в литерал, правый перезаписывает левого.
Множество — набор уникальных значений без порядка и без повторов: set(["frame", "motors", "frame"]) — это {"frame", "motors"}, повтор схлопнулся. Литерал множества — тоже фигурные скобки, но из значений, без пар «ключ: значение»: не перепутайте со словарём. Пересечение & оставляет то, что есть в обоих множествах: set(a) & set(b) — детали, входящие в оба комплекта; объединение | — то, что есть хоть где-то. Для стабильного порядка результат сортируют: sorted(...) из модуля 4 возвращает обычный список. Числа модуля — с настоящего дрона: «Модуль» — 1150 г без АКБ, питание LiPo 6S ёмкостью 5000 mAh, полезная нагрузка до 1200 г; whoop «Мини» — 32 г целиком, с АКБ 1S 450 mAh. Словарь spec с такими полями — настоящий конфиг, который скрипты бортового компьютера читают по именам.
Задания
0/10 заданий · 0/145 баллов
1. Ключ, get и KeyError
10 балл(ов)Журнал держит спецификацию в словаре spec = {"title": "Модуль", "mass_g": 1150} — ключа gps в нём нет. Выберите вариант, где верно назван результат spec.get("gps", "нет"), объяснено, почему spec["gps"] падает с KeyError, и правильно сказано, что может быть ключом словаря.