我需要构建一个部分
Inverted Index
.这样的东西:
l = {{x,{h,a,b,c}},{y,{c,d,e}}} iI[l] (* -> {{a,{x}},{b,{x,y}},{d,{y}},{e,{x}}} *)
我觉得这是很清楚的.在输入列表中,y …}是唯一的,而{a,c,..}不是.输出应该由#[[1]]排序.
现在,我这样做:
iI[list_List] := {#,list[[Position[list,#][[All,1]]]][[All,1]]} & /@ (Union@Flatten@Last@Transpose@list)
但是看起来太慢了,我应该能够应付军团,这看起来太复杂了.
比较你的结果的测试驱动:
words = DictionaryLookup[]; abWords = DictionaryLookup["ab" ~~ ___]; l = {#,RandomChoice[abWords,RandomInteger[{1,30}]]} & /@ words[[1 ;; 3000]]; First@Timing@iI[l] (* -> 5.312 *)
那么,加速的任何想法?
似乎是Reap-Sow的经典任务(由于@Heike在最终版本的改进):
原文链接:/javaschema/281384.htmliI[list_] := Sort[Reap[Sow @@@ list,_,List][[2]]]
然后,
iI[l] {{a,{x}}}
和
In[22]:= words=DictionaryLookup[]; abWords=DictionaryLookup["ab"~~___]; l={#,30}]]}&/@words[[1;;3000]]; First@Timing@iI[l] Out[25]= 0.047
编辑
这是一个具有类似(稍差)性能的替代版本:
iIAlt[list_] := Sort@Transpose[{#[[All,1,2]],#[[All,All,1]]}] &@ GatherBy[Flatten[Thread /@ list,1],Last];
有趣的是,Reap – Sow这里给出了比基于结构操作更快的解决方案.
编辑2
只是为了说明 – 对于喜欢基于规则的解决方案的人来说,这是一个基于Dispatch和ReplaceList的组合:
iIAlt1[list_] := With[{disp = Dispatch@Flatten[Thread[Rule[#2,#]] & @@@ list]},Map[{#,ReplaceList[#,disp]} &,Union @@ list[[All,2]]]]
但是,它比其他两个慢约2-3倍.