Ці ёсць лепшы спосаб захоўваць слоўнік TwoWay чым захоўваць яго зваротны асобна?

Улічваючы адзін-да-аднаму слоўнік (= биекция), генераваны ля

for key, value in someGenerator:
     myDict[key] = value

слоўнік зваротнага пошуку можа быць трывіяльным шляхам дадання

    invDict[value] = key

да для завесы. Але гэта Pythonic шлях? Ці павінен я замест таго, каб напісаць клас биекция (Dict) , які кіруе гэтым перавернутым слоўнікам дадаткова і забяспечвае другую функцыю пошуку? Ці ж такая структура (ці падобны) ужо існуе?

13
@Aya Падклас MutableMapping замест Dict . stackoverflow.com/questions/3387691/& hellip;
дададзена аўтар gotgenes, крыніца
@JonClements Гукі ідэальна падыходзіць, дзякуй! Я прымаю, што ў якасці адказу. Выкарыстанне зрэзаў для зваротнага пошуку выдатная ідэя ёсць
дададзена аўтар Tobias Kienzler, крыніца
@Aya Дзякуй за знаходжанне сапраўднага разявакі, я знайшоў толькі гэта адзін , які абмежаваны да паказаных Вамі асаблівы выпадак якіх-небудзь сутыкненняў ключ/значэнне. Дарэчы, гэтага пытання павінен быць адкрыты і зноў закрывае, як недарэка ваша прапанова замест таго, я казаў
дададзена аўтар Tobias Kienzler, крыніца
@Aya Дзякуй за знаходжанне сапраўднага разявакі, я знайшоў толькі гэта адзін , які абмежаваны да паказаных Вамі асаблівы выпадак якіх-небудзь сутыкненняў ключ/значэнне. Дарэчы, гэтага пытання павінен быць адкрыты і зноў закрывае, як недарэка ваша прапанова замест таго, я казаў
дададзена аўтар Tobias Kienzler, крыніца
@Aya Дзякуй за знаходжанне сапраўднага разявакі, я знайшоў толькі гэта адзін , які абмежаваны да паказаных Вамі асаблівы выпадак якіх-небудзь сутыкненняў ключ/значэнне. Дарэчы, гэтага пытання павінен быць адкрыты і зноў закрывае, як недарэка ваша прапанова замест таго, я казаў
дададзена аўтар Tobias Kienzler, крыніца
@Aya Хоць замена bidict ў __ GetItem __ з паспрабаваць: вяртанне self._fwd [keyorslice] \ п, акрамя TypeError: вяртанне self._bwd [keyorslice.stop] (ігнаруючы няправільнае выкарыстанне) можа паскорыць працэс, калі гэта неабходна. (Праклён, я хачу, пераносы радкоў у каментарах таму)
дададзена аўтар Tobias Kienzler, крыніца
@JonClements Я ў парадку з гэтай натацыяй - хэш не павінны быць упарадкаваны, так што няма ніякага спосабу, кавалачак можа быць няслушна вытлумачаны, калі ключы або значэння не з'яўляюцца відавочна цэлымі ліку ... Хоць гэта, верагодна, адна з прычын, каб выкарыстоўваць namedbidict замест
дададзена аўтар Tobias Kienzler, крыніца
@Aya Я паглядзеў на крыніцу, ён робіць гэта на самай справе. (Гл тут ), але для маіх мэтаў, якія, верагодна, нікчэмная. Але можна было б выкарыстоўваць namedbidict у гэтым выпадку
дададзена аўтар Tobias Kienzler, крыніца
Гэта наўрад ці адказ, і ў мяне няма ніякага вопыту ў рэчаіснасці выкарыстоўваць яго, каб асабіста рэкамендаваць яго небудзь. Проста да ведама, хоць, калі я правільна памятаю, там былі некаторыя даволі цяжкія дэбаты аб тым, ці быў API гэтай бібліятэкі Pythonic ці не выкарыстоўваючы лустачку абазначэнне. Але, прыгажосць у вачах таго, хто глядзіць, і ўсё гэта.
дададзена аўтар Jon Clements, крыніца
Што пра гэта bidict
дададзена аўтар Jon Clements, крыніца
@gotgenes я не бачу, як гэта вырашае праблему прадукцыйнасці, звязаны з выклікам __ GetItem __ .
дададзена аўтар Aya, крыніца
@gotgenes я не бачу, як гэта вырашае праблему прадукцыйнасці, звязаны з выклікам __ GetItem __ .
дададзена аўтар Aya, крыніца
Мяркуючы, што там не перасякаюцца паміж тыпамі ключ/значэнне, іншы варыянт быў бы нешта накшталт: клас Bidict (дыктуе): Абарону __setitem __ (я, да, v): дыктуе .__ SetItem __ (я, да, v); Дыктуюць .__ SetItem __ (я, v, к) г.зн. выкарыстоўваць адзін і той жа Dict для абодвух кірункаў, але гэта не можа быць дарэчы ў вашым выпадку.
дададзена аўтар Aya, крыніца
@TobiasKienzler Ну, я нядаўна давялося аптымізаваць даволі складаную рэкурсіўная функцыю, якая ў цяперашні час пад назвай 150000 раз, так што я правёў некаторы час, прафіляванне розныя метады з Cprofile , і атрымалася зэканоміць шмат працэсарнага часу, па выкарыстоўваючы d [K], калі да ў в падыход. Пазней я змяніў яго выкарыстоўваць D = collections.defaultdict (лямбда: Не); v = d [да]; вярнуцца something_else, калі v з'яўляецца None яшчэ v , які быў нават лепш, так як яна патрабуе толькі адзін прагляд ключа, ключ промахаў толькі калі-небудзь здараецца адзін раз, а defaultdict рэалізуецца ў C. Вы маеце рацыю аб namedbidict - Я няправільна зразумеў гэта ў першы раз.
дададзена аўтар Aya, крыніца
@TobiasKienzler Сапраўды. Спроба/за выключэннем блока будзе запаволіць ход падзей, а таксама. На практыцы, я знайшоў вяртанне d [да], калі да ў d яшчэ something_else значна хутчэй, чым абодва паспрабаваць: вяртанне д [да] \ п, акрамя KeyError: вяртанне something_else і < код> вяртанне d.get (да, something_else) , то ёсць два ключавых пошукі хутчэй, чым дазваляе Python генераваць выключэнне і/або выкліку метаду асобніка. Асабіста я не думаю, што забяспечвае досыць дадатковыя функцыянальныя магчымасці (у параўнанні з толькі з дапамогай двух dicts), каб апраўдаць свае праблемы з прадукцыйнасцю, але калі гэта не праблема, то, па меншай меры, мае годнасць быць простым ў выкарыстанні.
дададзена аўтар Aya, крыніца
@TobiasKienzler Да. Падобна на тое, namedbidict будзе больш эфектыўным.
дададзена аўтар Aya, крыніца
Мяркуючы па ўсім, bidict проста абгортвае два асобных слоўнікаў Python з прамога і зваротнага адлюстравання, так што гэта не больш эфектыўна, чым рабіць тое ж самае сябе. На самай справе, калі вы робіце шмат ключавых пошукі, гэта будзе нашмат больш павольна з-за накладныя выдаткі выкліку функцыі.
дададзена аўтар Aya, крыніца

6 адказы

Тое, што я зрабіў у мінулым, стварылі reversedict <�код /> функцыя, якая будзе прымаць Dict і вярнуць супрацьлеглае адлюстраванне, альбо значэння ключоў, калі я ведаў, што гэта быў адзін-да-аднаму (кіданне выключэння на бачачы ж значэнне двойчы), або значэнне ў спісы ключоў, калі гэта не было. Такім чынам, замест таго, каб пабудаваць два dicts адначасова кожны раз, калі я хацеў зваротны погляд уверх, я мог бы стварыць свой dicts як нармальныя і проста выклікаць радавую reversedict функцыю ў канцы.

Тым не менш, здаецца, што bidict рашэнне, якое Джон згадваецца ў каментарах, верагодна, лепш адзін. (Мой reversedict функцыя, здаецца, яго bidict ў ~ аператар).

5
дададзена
bidict ідэальна падыходзіць для маіх мэтаў - гэта ў асноўным захоўвае зваротны слоўнік ўнутры, але паляпшае доступ з дапамогай аператара лустачкі
дададзена аўтар Tobias Kienzler, крыніца

Тое, што я зрабіў у мінулым, стварылі reversedict <�код /> функцыя, якая будзе прымаць Dict і вярнуць супрацьлеглае адлюстраванне, альбо значэння ключоў, калі я ведаў, што гэта быў адзін-да-аднаму (кіданне выключэння на бачачы ж значэнне двойчы), або значэнне ў спісы ключоў, калі гэта не было. Такім чынам, замест таго, каб пабудаваць два dicts адначасова кожны раз, калі я хацеў зваротны погляд уверх, я мог бы стварыць свой dicts як нармальныя і проста выклікаць радавую reversedict функцыю ў канцы.

Тым не менш, здаецца, што bidict рашэнне, якое Джон згадваецца ў каментарах, верагодна, лепш адзін. (Мой reversedict функцыя, здаецца, яго bidict ў ~ аператар).

5
дададзена
bidict ідэальна падыходзіць для маіх мэтаў - гэта ў асноўным захоўвае зваротны слоўнік ўнутры, але паляпшае доступ з дапамогай аператара лустачкі
дададзена аўтар Tobias Kienzler, крыніца

Тое, што я зрабіў у мінулым, стварылі reversedict <�код /> функцыя, якая будзе прымаць Dict і вярнуць супрацьлеглае адлюстраванне, альбо значэння ключоў, калі я ведаў, што гэта быў адзін-да-аднаму (кіданне выключэння на бачачы ж значэнне двойчы), або значэнне ў спісы ключоў, калі гэта не было. Такім чынам, замест таго, каб пабудаваць два dicts адначасова кожны раз, калі я хацеў зваротны погляд уверх, я мог бы стварыць свой dicts як нармальныя і проста выклікаць радавую reversedict функцыю ў канцы.

Тым не менш, здаецца, што bidict рашэнне, якое Джон згадваецца ў каментарах, верагодна, лепш адзін. (Мой reversedict функцыя, здаецца, яго bidict ў ~ аператар).

5
дададзена
bidict ідэальна падыходзіць для маіх мэтаў - гэта ў асноўным захоўвае зваротны слоўнік ўнутры, але паляпшае доступ з дапамогай аператара лустачкі
дададзена аўтар Tobias Kienzler, крыніца

калі вы хочаце O (часопіс (п)) час для доступу да значэнняў, то вам трэба як прадстаўленне карты і прадстаўленне зваротнага адлюстравання.

у адваротным выпадку лепшае, што вы можаце зрабіць, гэта O (часопіс (п)) у адным кірунку і Аб (п) у іншай.

Edit: not O(log(n)), thanks Claudiu, but you are still going to need two data structures to implement the quick access times. And this will be more or less the same space as a dict and an inverse dict.

0
дададзена
dicts не мае O (часопіс (п)) пошуку, яны амартызуецца O (1) пошук ...
дададзена аўтар Claudiu, крыніца
так, павінны былі глядзець, што перш, чым я адправіў :)
дададзена аўтар Zackkenyon, крыніца

калі вы хочаце O (часопіс (п)) час для доступу да значэнняў, то вам трэба як прадстаўленне карты і прадстаўленне зваротнага адлюстравання.

у адваротным выпадку лепшае, што вы можаце зрабіць, гэта O (часопіс (п)) у адным кірунку і Аб (п) у іншай.

Edit: not O(log(n)), thanks Claudiu, but you are still going to need two data structures to implement the quick access times. And this will be more or less the same space as a dict and an inverse dict.

0
дададзена
dicts не мае O (часопіс (п)) пошуку, яны амартызуецца O (1) пошук ...
дададзена аўтар Claudiu, крыніца
так, павінны былі глядзець, што перш, чым я адправіў :)
дададзена аўтар Zackkenyon, крыніца

калі вы хочаце O (часопіс (п)) час для доступу да значэнняў, то вам трэба як прадстаўленне карты і прадстаўленне зваротнага адлюстравання.

у адваротным выпадку лепшае, што вы можаце зрабіць, гэта O (часопіс (п)) у адным кірунку і Аб (п) у іншай.

Edit: not O(log(n)), thanks Claudiu, but you are still going to need two data structures to implement the quick access times. And this will be more or less the same space as a dict and an inverse dict.

0
дададзена
dicts не мае O (часопіс (п)) пошуку, яны амартызуецца O (1) пошук ...
дададзена аўтар Claudiu, крыніца
так, павінны былі глядзець, што перш, чым я адправіў :)
дададзена аўтар Zackkenyon, крыніца