需要从嵌套列表维护秩序删除重复(Need to remove duplicates from a n

2019-10-28 14:58发布

我有一个像下面的列表

L = [[1,2],[1,3],[1,4],[2,1],[2,5],[3,1],[3,2]]

输出应该是

[[1,2],[1,3],[1,4],[2,5],[3,2]]

请注意,在对和元素的顺序必须被保留。 换句话说,由于要素订单需要保留的对,以及我不能对列表进行排序。 例如,我需要的最后一个元素[3,2]被保存下来。 如果我对它们进行排序和删除重复这将被更改为[2,3],我不想要的。 此外,当我说我需要删除重复[1,2]或[2,1]被认为是重复的,我希望保留这个[1,2]。

Answer 1:

这种工作原理类似于从常规列表,同时保留顺序删除重复 ,但我们需要做一些事情不是子列表可哈希和子列表是不相关的顺序。

我们可以用冷冻组,可以同时解决这两个问题。

>>> lst = [[1,2],[1,3],[1,4],[2,1],[2,5],[3,1],[3,2]] 
>>> seen = set()
>>> result = []
>>> 
>>> for x in lst:
...     s = frozenset(x)
...     if s not in seen:
...         result.append(x)
...         seen.add(s)
... 
>>> result
[[1, 2], [1, 3], [1, 4], [2, 5], [3, 2]]


Answer 2:

unique_everseen在功能itertools食谱中的文档不正是你所需要的:

>>> lst = [[1,2],[1,3],[1,4],[2,1],[2,5],[3,1],[3,2]]
>>> list(unique_everseen(lst, key=frozenset))
[[1, 2], [1, 3], [1, 4], [2, 5], [3, 2]]

其基本思路是,它让一组迄今所看到的所有值,并跳过这已经在设置的任何值。

key功能的工作方式相同,如sortmax等,在解释的排序HOWTO 。 你想有不同的顺序匹配相同的价值观两个列表,所以我们需要比较集中的每个列表的价值观,而不是名单本身。 (我们需要的原因frozenset ,而不是setset是可变的,因此不能存储在一组。)


如果你有在你的子表超过2元,该问题将是不明确的。 如果你有,比如说, [1, 1, 2][1, 2, 2]你希望它们被认为是重复的,或不?

  • 如果是的话:那你对待他们一组,所以使用key=frozenset
  • 如果没有:那你把它们当作一个多集。 多集的最好的Python的实现是collections.Counter ,但没有FrozenCounter (和建立一个只用于此目的可能是矫枉过正)。 您可以模拟一个在几个方面:
    • key=lambda sublist: frozenset(Counter(sublist).items())
    • key=lambda sublist: sorted(Counter(sublist).items())
    • key=lambda sublist: tuple(sorted(sublist))

由于您最初的想法是排序的子表,其中,因为你需要为原始值,结束了,只是不能接受没有排序的价值,我认为最后的这些选项是最有可能是你想要的,但这是真的还是只是一个猜测。


您可以复制并粘贴文档到你的代码的功能:

from itertools import *

def unique_everseen(iterable, key=None):
    "List unique elements, preserving order. Remember all elements ever seen."
    # unique_everseen('AAAABBBCCDAABBB') --> A B C D
    # unique_everseen('ABBCcAD', str.lower) --> A B C D
    seen = set()
    seen_add = seen.add
    if key is None:
        for element in filterfalse(seen.__contains__, iterable):
            seen_add(element)
            yield element
    else:
        for element in iterable:
            k = key(element)
            if k not in seen:
                seen_add(k)
                yield element

......或者安装第三方库more_itertools并使用其unique_everseen从那里。 或不同的第三方库toolz有一个名为同等功能unique



文章来源: Need to remove duplicates from a nested list preserving the order