Есть ли способ получить доступ к значениям словаря по неполным ключам? - PullRequest
0 голосов
/ 22 апреля 2020

Мне нужен «diccionary», ключами которого являются строки, но вам не нужно вводить все слово, чтобы получить доступ к соответствующему значению, только некоторые из первых символов, их достаточно, чтобы не соответствовать ни одному другому ключу (аналогично вводу в консоли, и нажмите tab, и консоль угадывает правильную команду, потому что другие не совпадают с ней)

Например, в словаре:

dicc = { 'suma':fun_suma, 'resta':fun_resta, 'producto':fun_producto }

Мне нужно это dicc['pr'], dicc['prod'], dicc['produc'], даже просто dicc['p'], возвращает fun_producto (в этом примере, поскольку введенные строки не соответствуют ни одной другой клавише).

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

ОБНОВЛЕНИЯ:

  1. Да, я ошибся, словарь python использует таблицу Ha sh, а не дерево. Я перепутал свои воспоминания.
  2. Да, dicc ['p'] был драматическим примером c, но я использовал его только для того, чтобы показать, что в некоторых случаях он может так сильно сократить запись каратэров. Конечно, это будет полезно, только если ключи хорошо известны и имеют конечный набор, например, синтаксический анализатор.

1 Ответ

1 голос
/ 22 апреля 2020

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

Это может быть начало, оно вернет первый ключ, который соответствует префиксу:

from collections import UserDict

class PrefixDict(UserDict):
    def __setitem__(self, name, value):
        if not isinstance(name, str):
            raise ValueError("Keys must be strings")
        super().__setitem__(name, value)

    def __getitem__(self, name):
        try:
            return next(self.data[k] for k in self.data.keys() if k.startswith(name))
        except StopIteration as error:
            raise KeyError(f"Prefix '{name}' not found") from None

dicc = PrefixDict({'suma':'fun_suma', 'resta':'fun_resta', 'producto':'fun_producto' })

dicc['pr']
#'fun_producto'

dicc["q"]
# raises KeyError

dicc[""]
# ?? 

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

...