Комментарии 25
Может имеет смысл добавить режим, в котором проверяется наличие коллизии между ключами начального/прямого и обратного словаря? Например, можно выбрасывать исключение в таком случае. И добавить проверку, что все значения прямого словаря уникальные. И также выбрасывать исключение в случае обнаружения дубликатов.
Например, в одной системе тип документа "Договор", а в другой "Contract".
одна система принимает буквенный код валюты "RUB", а другая числовой "643"
А что вы будете делать, когда систем станет три?
160 элементов - это всё ещё "мало". Были бы сотни тысяч, можно было бы подумать об эффективном хранении и из-за этого - об эффективном доступе. А тут...
Отдельный минус подхода - смешивание ключей туда-обратно. В языке со слабой типизацией можно накосячить с лёгкостью необычайной. Лучше соблюдать чистоту рук, однако!
Но кстати, быстрое-и-грязное решение - это напихать ключи в один словарь
def make_bimap(src): # src - dict
dst = {}
dst.update(src)
dst.update((v, k) for (k, v) in src.items())
return dst
Но при этом надо удостовериться, что нет конфликта ключей в обратном направлении.
Ну и не забываем про наследие предков. Бимапы люди делали издревле, и быстрый поиск даёт, например, PyPy.bidict.
я наверное не знал что это бимап называтся, того и не нашел нечего))). Но все ровно было интересно по изобретать
В современных питонах можно проще
a = {"one": 1, "two": 2}
bi = {**a, **{v:k for k, v in a.items()}}
bi
{'one': 1, 'two': 2, 1: 'one', 2: 'two'}
да, по сути можно, но я сделал интерфейс для этого, и пользователь может не думать что происходит под капотом. Еще добавились некоторые фишки, типа приведения ключа к типу ключа и дефолтные значения
assert digit_mapping['two'] == 2
assert digit_mapping[2] == 'two'
assert digit_mapping['2'] == 'two'
Так-то каждый может. А вот сделайте такую мапу, у которой спрашиваешь про новый договор: m.get("договор №18"), а она возвращает: "составлен, одобрен, подписан и уже завершён, деньги уже на вашем счету". Вот это я понимаю.
Скорее всего, что подход "би"-маппинга стоит решать на уровне получения объектов из БД. Это работает, если возможно контролировать БД всех систем.
В остальных случаях идея может быть улучшена, если известна система "источник" и система "назначение", а они известны в текущем примере, поскольку в этом случае маппинг выполняется с помощью только одного словаря "sourse: destination" и исключено появление каких-либо ошибок по ключам, о которых писали предыдущие комментаторы.
PS. Код не работает, если values вmapping: dict
не hashable. А на __init__ это не проверяется.
Был бы такой объект в python, в котором происходит маппинг не зависимо
от передаваемого ключа. Передаешь RUB получаешь 643, передаешь 643
получаешь RUB
Он есть.from enum import Enum
class Currencies(Enum):
RUB = 840
Currencies['RUB']
Out[8]: <_Currencies.RUB: 840>
Currencies(840)
Out[10]: <_Currencies.RUB: 840>
Прикольно, не знал что он так работает. А он значения отдаст тоже как хэш-таблица? Почитал исходники, не совсем понял как он работает. По сути то что мне и нужно, но если бы я знал, не придумал бы сам такой велосипед))). У Enum по разному надо вызывать метод чтобы получить значения (Currencies['RUB'], Currencies(840)) а меня однообразно (может это преимущество или недостаток)))
assert digit_mapping['two'] == 2
assert digit_mapping[2] == 'two'
assert digit_mapping['2'] == 'two'
Не уверен, что правильно понял Ваш вопрос, но хранит енам данные в дикте, да.
from enum import Enum
class Currencies(Enum):
RUB = 840
Currencies.__members__
Out[6]: mappingproxy({'RUB': <Currencies.RUB: 840>})
rub = Currencies.__members__['RUB']
rub.value
Out[8]: 840
rub.name
Out[9]: 'RUB'
не совсем понял как он работает
Загляните в: Currencies.__dict__, там статичесикие аттрибуты на каждый элемент и две мапы прямая и обратная.
Скажите а как сделать так, чтобы f(a, b)=c где с линейная зависимость от некой функции в которую входят а и b!? То есть а и b подставляем в словарь и он выдает с который монотонно возрастает от а и b и линейный сам по себе!?
Если хотите чтобы работало как настоящий словарь, то наследуйтесь от https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping.
Если хотите еще более формализовать свои эксперементы, то можно залить ваш код сюда.
https://github.com/TheAlgorithms/Python/tree/master/data_structures/hashing
Придётся правда перевести всё на английский и детально расписать ограничения.
Класс Reverse Mapping на Python