Robię tę funkcję przełącznika w Pythonie, gdzie muszę śledzić, kto z kim rozmawia, więc jeśli Alice -> Bob, to oznacza, że Bob -> Alice.
Tak, mógłbym wypełnić dwie mapy skrótów, ale zastanawiam się, czy ktoś ma pomysł, aby to zrobić z jedną.
Lub zasugeruj inną strukturę danych.
Nie ma wielu rozmów. Powiedzmy, że dotyczy to centrum obsługi klienta, więc kiedy Alicja wybierze numer z centrali, będzie rozmawiać tylko z Bobem. Jego odpowiedzi również trafiają tylko do niej.
Odpowiedzi:
Możesz utworzyć własny typ słownika, tworząc podklasy
dict
i dodając odpowiednią logikę. Oto podstawowy przykład:I to działa tak:
Jestem pewien, że nie omówiłem wszystkich przypadków, ale to powinno zacząć.
źródło
.add
metodę, abyś mógł robić takie rzeczy, jakd.add('Bob', 'Alice')
zamiast używać składni, którą pokazałem. Chciałbym również dołączyć obsługę błędów. Ale masz podstawowy pomysł. :)d['foo'] = 'baz'
trzeba by dodatkowo usunąćbar
klucz).dict
powoduje tutaj pewne mylące zachowanie, ponieważ jeśli utworzysz obiekt z pewną zawartością początkową, struktura zostanie zerwana.__init__
musi zostać zastąpiony, aby konstrukcja takad = TwoWayDict({'foo' : 'bar'})
działała poprawnie.pip install bidict
. URL: pypi.python.org/pypi/bidictW twoim szczególnym przypadku możesz przechowywać oba w jednym słowniku:
Ponieważ to, co opisujesz, jest relacją symetryczną.
A -> B => B -> A
źródło
Wiem, że to starsze pytanie, ale chciałem wspomnieć o innym świetnym rozwiązaniu tego problemu, a mianowicie o pakiecie python bidict . Jest niezwykle prosty w użyciu:
źródło
Po prostu zapełniłbym drugi hash za pomocą
źródło
reverse_map = dict(reversed(item) for item in forward_map.items())
my_dict.update(dict(reversed(item) for item in my_dict.items()))
Unexpected type(s): (Generator[Iterator[Union[str, Any]], Any, None]) Possible types: (Mapping) (Iterable[Tuple[Any, Any]])
. Jakieś pomysły, jak pozbyć się ostrzeżenia?Dwie mapy skrótów są prawdopodobnie najszybszym rozwiązaniem przy założeniu, że można zaoszczędzić pamięć. Umieściłbym je w jednej klasie - obciążenie programisty polega na zapewnieniu prawidłowej synchronizacji dwóch map skrótów.
źródło
mydict[:value]
uzyskaniekey
(kosztem pewnej wydajności)Masz dwa oddzielne problemy.
Masz obiekt „Rozmowa”. Odnosi się do dwóch osób. Ponieważ osoba może prowadzić wiele rozmów, istnieje relacja „wiele do wielu”.
Masz mapę od osoby do listy konwersacji. Nawrócenie będzie miało parę Osób.
Zrób coś takiego
źródło
Nie, naprawdę nie da się tego zrobić bez utworzenia dwóch słowników. Jak można by to zaimplementować za pomocą tylko jednego słownika, jednocześnie oferując porównywalną wydajność?
Lepiej jest utworzyć niestandardowy typ, który zawiera dwa słowniki i udostępnia żądaną funkcjonalność.
źródło
Mniej rozwlekły sposób, nadal używający odwrócenia:
źródło
Możesz być w stanie użyć,
DoubleDict
jak pokazano w przepisie 578224 w książce kucharskiej języka Python .źródło
Innym możliwym rozwiązaniem jest zaimplementowanie podklasy
dict
, która przechowuje oryginalny słownik i śledzi jego odwróconą wersję. Przechowywanie dwóch oddzielnych poleceń może być przydatne, jeśli klucze i wartości nakładają się.Przykład:
źródło
Na pypi znajduje się rozszerzona biblioteka kolekcji: https://pypi.python.org/pypi/collections-extended/0.6.0
Korzystanie z klasy bijection jest tak proste, jak:
źródło
Podoba mi się sugestia licytanta w jednym z komentarzy.
pip install bidict
Zastosowanie:
Ponieważ nie ma na ten temat wielu dokumentów. Ale wszystkie funkcje, których potrzebuję, działają poprawnie.
Wydruki:
źródło
Moduł rozszerzenia kjbuckets C zapewnia strukturę danych "grafową", która moim zdaniem daje ci to, czego chcesz.
źródło
Oto jeszcze jedna dwukierunkowa implementacja słownika poprzez rozszerzenie
dict
klasy Pythona na wypadek, gdybyś nie lubił żadnego z tych innych:Użyj go jako normalnego słownika Pythona, z wyjątkiem konstrukcji:
źródło
Sposób, w jaki lubię robić tego typu rzeczy, jest taki:
źródło