我想从列表列表中删除重复数据删除,保持子列表结构不变。
E.g。
{{1, 7, 8}, {4, 3}, {4, 1, 9}, {9, 2}}
变为
{{1, 7, 8}, {4, 3}, {9}, {2}}
这是嵌套的范围,空的子列表是可以的。
答案 0 :(得分:11)
这是一个经典的伎俩:
list = {{1, 7, 8}, {4, 3}, {4, 1, 9}, {9, 2}}
Module[{f},
f[x_] := (f[x] = Sequence[]; x);
Map[f, list, {2}]
]
要了解它是如何工作的,请考虑第一次评估f[1]
时会发生什么。 f[1]
将评估为(f[1]=Sequence[]); 1
,然后评估为1
。所以现在已经为f[1]
做了定义。下次评估f[1]
时,它只会评估为Sequence[]
。
因此,第一次为参数计算f
时,它返回该参数。评估它的第二个(或第三个等)时间,它返回Sequence[]
。 Sequence[]
具有完全从表达式中删除的属性,即{1, Sequence[], 3}
将评估为{1, 3}
。
总而言之,该函数的作用是:第一次看到一个元素时,它会将元素替换为自身(单独留下)。第二次它看到相同的元素,它会删除它。我将此函数映射到“level 2”,因此它仅对子列表的元素起作用。
答案 1 :(得分:3)
您可以使用Complement
进行此操作,您唯一需要做的就是存储您已经看过的所有元素。在开始时,所有看到的元素a
的列表为空,然后逐步添加子列表中的所有数字。每个步骤都使用此累积列表来删除已经看过的所有数字:
DeleteDuplicatesList[l_List] :=
Block[{a = {}},
Table[With[{b = a},
a = Union[a, c];
Complement[c, b]], {c, l}]
];
l = {{1, 7, 8}, {4, 3}, {4, 1, 9}, {9, 2}};
DeleteDuplicatesList[l]
答案 2 :(得分:2)
它并不优雅,但它完成了工作:
t = {{1, 7, 8}, {4, 3}, {4, 1, 9}, {9, 2}};
Delete[t, Flatten[Rest[Position[t, #]] & /@ (DeleteDuplicates[Flatten[t]]), 1]]
DeleteDuplicates
...将返回t中的数字集,而不是多集。
Rest[Position[
...将返回重复的位置。
Delete
删除了所说的副本。