✅ Решения заданий

⚡ Решения в двух словах

  • Длины слов — dict comprehension с len().
  • Замена чисел на слова — новый словарь через mapping.get().
  • Отчёт — Optional[list[str]] и проверка на пустоту.
  • Функция высшего порядка — Callable[[Any], Any] и list comprehension.
⚠️ Рекомендация: попробуйте решить задания самостоятельно, прежде чем смотреть ответы. Решения — это последняя инстанция, когда собственные попытки исчерпаны.

Решение задания 1. Длины слов

# task1_solution.py
def get_word_lengths(words: list[str]) -> dict[str, int]:
    """
    Возвращает словарь, где ключи — строки, а значения — их длины.

    :param words: Список строк.
    :return: Словарь с длинами строк.
    """
    return {word: len(word) for word in words}


words = ["apple", "banana", "cherry"]
print(get_word_lengths(words))

Логика решения: dict comprehension проходит по каждому слову и сразу формирует пару «слово: длина». Это короче и понятнее, чем создавать пустой словарь и заполнять его в цикле.

Решение задания 2. Из чисел в слова

# task2_solution.py
def replace_numbers_with_words(
    data: dict[str, int],
    mapping: dict[int, str]
) -> dict[str, str]:
    """
    Заменяет числовые значения в словаре data на строки из mapping.

    :param data: Словарь с числовыми значениями.
    :param mapping: Словарь сопоставлений число → строка.
    :return: Новый словарь со строковыми значениями.
    """
    return {key: mapping.get(value, str(value)) for key, value in data.items()}


number_to_word = {1: "один", 2: "два", 3: "три"}
data = {"x": 1, "y": 2, "z": 3}
print(replace_numbers_with_words(data, number_to_word))

Логика решения: функция создаёт новый словарь, не изменяя исходный. mapping.get(value, str(value)) безопасно обрабатывает отсутствующие ключи: если числа нет в словаре сопоставлений, подставляется строковое представление числа.

Решение задания 3. Генерация отчёта

# task3_solution.py
from typing import Optional


def generate_report(name: str, achievements: Optional[list[str]] = None) -> str:
    """
    Генерирует отчёт о достижениях пользователя.

    :param name: Имя пользователя.
    :param achievements: Список достижений (необязательный).
    :return: Строка с отчётом.
    """
    if not achievements:
        return f"{name}: Нет достижений"
    return f"{name}: {', '.join(achievements)}"


name = "Alice"
achiev = ["Won chess tournament", "Completed marathon", "Published a book"]
print(generate_report(name, achiev))
print(generate_report("Bob"))

Логика решения: параметр achievements имеет значение по умолчанию None, поэтому его можно не передавать. Проверка if not achievements сработает и для None, и для пустого списка. В современном Python вместо Optional[list[str]] можно писать list[str] | None.

Решение задания 4. Обработка элементов функцией

# task4_solution.py
from typing import Any, Callable


def apply_to_all(
    func: Callable[[Any], Any],
    elements: list[Any]
) -> list[Any]:
    """
    Применяет переданную функцию ко всем элементам списка.

    :param func: Функция, принимающая элемент списка и возвращающая результат.
    :param elements: Список произвольных элементов.
    :return: Новый список с результатами применения функции.
    """
    return [func(item) for item in elements]


numbers = [1, 2, 3, 4, 5]
result = apply_to_all(lambda x: x * 2, numbers)
print(result)

Логика решения: Callable[[Any], Any] говорит, что параметр func — это функция с одним аргументом любого типа и результатом любого типа. Реализация через list comprehension создаёт новый список, не изменяя исходный.