Time efficient Partial Inverted Index building

我怕爱的太早我们不能终老 提交于 2019-12-03 12:13:34

Seems a classic task for Reap-Sow (improvement in the final version due to @Heike):

iI[list_] := Sort[Reap[Sow @@@ list, _, List][[2]]] 

Then,

iI[l]

{{a, {x}}, {b, {x}}, {c, {x, y}}, {d, {y}}, {e, {y}}, {h, {x}}}

and

In[22]:= 
words=DictionaryLookup[];
abWords=DictionaryLookup["ab"~~___];
l={#,RandomChoice[abWords,RandomInteger[{1,30}]]}&/@words[[1;;3000]];
First@Timing@iI[l]
Out[25]= 0.047

EDIT

Here is an alternative version with a similar (slightly worse) performance:

iIAlt[list_] :=
   Sort@Transpose[{#[[All, 1, 2]], #[[All, All, 1]]}] &@
           GatherBy[Flatten[Thread /@ list, 1], Last];

It is interesting that Reap - Sow here gives an even slightly faster solution than the one based on structural operations.

EDIT 2

Just for an illustration - for those who prefer rule-based solutions, here is one based on a combination of Dispatch and ReplaceList:

iIAlt1[list_] :=
   With[{disp = Dispatch@Flatten[Thread[Rule[#2, #]] & @@@ list]},
       Map[{#, ReplaceList[#, disp]} &, Union @@ list[[All, 2]]]]

It is about 2-3 times slower than the other two, though.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!