这是一种方法:
DeleteDuplicates[list, First@#1 === First@#2 &]
编辑
请注意,下面的时间安排和讨论基于 M7
经过一番思考,我找到了一个解决方案,对于大型列表来说,它(至少)会快一个数量级,有时会快两个数量级,对于这种特殊情况(可能,更好的说法是下面的解决方案将具有不同的计算复杂度):
Clear[delDupBy];
delDupBy[nested_List, n_Integer] :=
Module[{parts = nested[[All, n]], ord, unpos},
ord = Ordering[parts];
unpos = Most@Accumulate@Prepend[Map[Length, Split@parts[[ord]]], 1];
nested[[Sort@ord[[unpos]]]]];
基准测试:
In[406]:=
largeList = RandomInteger[{1,15},{50000,2}];
In[407]:= delDupBy[largeList,1]//Timing
Out[407]= {0.016,{{13,4},{12,1},{1,6},{6,13},{10,12},{7,15},{8,14},
{14,4},{4,1},{11,9},{5,11},{15,4},{2,7},{3,2},{9,12}}}
In[408]:= DeleteDuplicates[largeList,First@#1===First@#2&]//Timing
Out[408]= {1.265,{{13,4},{12,1},{1,6},{6,13},{10,12},{7,15},{8,14},{14,4},
{4,1},{11,9},{5,11},{15,4},{2,7},{3,2},{9,12}}}
这特别值得注意,因为DeleteDuplicates 是一个内置函数。我可以盲目猜测DeleteDuplicates 与用户定义的测试使用的是二次时间成对比较算法,而delDupBy 在列表大小中是n*log n。
我认为这是一个重要的教训:在使用自定义测试时应该注意内置函数,例如Union、Sort、DeleteDuplicates 等。我在 this Mathgroup 线程中更广泛地讨论了它,其中还有其他有见地的回复。
最后,让我提一下,在here 之前已经提出过这个问题(强调效率)。我将在这里重现我为第一个(或通常为n-th)元素是正整数(推广到任意整数很简单)的情况给出的解决方案。:
Clear[sparseArrayElements];
sparseArrayElements[HoldPattern[SparseArray[u___]]] := {u}[[4, 3]]
Clear[deleteDuplicatesBy];
Options[deleteDuplicatesBy] = {Ordered -> True, Threshold -> 1000000};
deleteDuplicatesBy[data_List, n_Integer, opts___?OptionQ] :=
Module[{fdata = data[[All, n]], parr,
rlen = Range[Length[data], 1, -1],
preserveOrder = Ordered /. Flatten[{opts}] /. Options[deleteDuplicatesBy],
threshold = Threshold /. Flatten[{opts}] /. Options[deleteDuplicatesBy], dim},
dim = Max[fdata];
parr = If[dim < threshold, Table[0, {dim}], SparseArray[{}, dim, 0]];
parr[[fdata[[rlen]]]] = rlen;
parr = sparseArrayElements@If[dim < threshold, SparseArray@parr, parr];
data[[If[preserveOrder, Sort@parr, parr]]]
];
它的工作方式是使用第一个(或通常是n-th)元素作为某些位置
我们预先分配的巨大表,利用它们是正整数)。在某些情况下,这可以给我们带来疯狂的表现。观察:
In[423]:= hugeList = RandomInteger[{1,1000},{500000,2}];
In[424]:= delDupBy[hugeList,1]//Short//Timing
Out[424]= {0.219,{{153,549},{887,328},{731,825},<<994>>,{986,150},{92,581},{988,147}}}
In[430]:= deleteDuplicatesBy[hugeList,1]//Short//Timing
Out[430]= {0.032,{{153,549},{887,328},{731,825},<<994>>,{986,150},{92,581},{988,147}}}