def create_node(name: str, phone: str, next: dict = None): return {"name": name, "phone": phone, "next": next} def create_linked_list(data: list[dict]) -> dict: """Создание связного списка по массиву словарей. :param data: Список словарей с параметрами: {'name': str, 'phone': str, next: dict | None} :type data: list[dict] :raises ValueError: Ошибка при подаче на вход пустого списка :return: Связный список оформленный по примеру: {'name': str, 'phone': str, next: dict | None} :rtype: dict """ if data is None or len(data) == 0: raise ValueError("Список пустой!") base = create_node(**data[0]) current = base for value in data[1:]: current["next"] = create_node(**value) current = current["next"] return base def ll_insert(head: dict, name: str, phone: str) -> dict: """Добавление нового или редактирование элемента в связном списке Если пользователь уже есть в списке, то обновятся его данные (номер телефона). В случае если данных нет, то они добавляются в конец. :param head: Список словарей с параметрами: {'name': str, 'phone': str, next: dict | None} :type head: dict :param name: Имя пользователя (не должно повторятся с имеющимися) :type name: str :param phone: Номер телефона пользователя (не должно повторятся с имеющимися) :type phone: str :raises ValueError: Ошибка при подаче на вход пустого списка :return: Возвращает связный список с обновленными данными :rtype: dict """ if head is None: raise ValueError("Словарь пустой!") current = head while current["next"] is not None: if current.get("name") == name or current.get("phone") == phone: current["name"] = name current["phone"] = phone break current = current.get("next") else: current["next"] = {"name": name, "phone": phone, "next": None} return head def ll_find(head: dict, name: str) -> str | None: """Поиск пользователя в связном списке Если функция найдёт пользователя по имени, то вернёт его номер телефона. В противном случае будет возвращено значение None. В случае повторяющихся имен в списке, выведется выше стоящие :param head: Список словарей с параметрами: {'name': str, 'phone': str, next: dict | None} :type head: dict :param name: Имя пользователя :type name: str :raises ValueError: Ошибка при подаче на вход пустого списка :return: Возвращает номер телефона найденного пользователя, иначе None :rtype: str | None """ if head is None: raise ValueError("Словарь пустой!") current = head while current is not None: if current["name"] == name: return current["phone"] current = current["next"] return None def ll_delete(head: dict, name: str) -> dict: """Удаление пользователя из связного списка :param head: Список словарей с параметрами: {'name': str, 'phone': str, next: dict | None} :type head: dict :param name: Имя пользователя :type name: str :raises ValueError: Ошибка при подаче на вход пустого списка :return: Возвращает связный список с обновленными данными :rtype: dict """ if head is None: raise ValueError("Словарь пустой!") if head.get("name") == name: head = head.get("next") return head current = head while current.get("next") is not None: if current.get("next").get("name") == name: current["next"] = current.get("next").get("next") return head current = current.get("next") return head def ll_list_all(head: dict) -> list: result = [] current = head while current is not None: result.append({"name": current.get("name"), "phone": current.get("phone")}) current = current.get("next") return result