删除Python中列表中的重复列表

Remove duplicated lists in list of lists in Python

我在这里看到了一些非常相关的问题,但它们的答案对我来说不起作用。我有一个列表,其中有些子列表是重复的,但它们的元素可能是无序的。例如

g = [[1, 2, 3], [3, 2, 1], [1, 3, 2], [9, 0, 1], [4, 3, 2]]

当然,根据我的问题,输出应该是:

g = [[1,2,3],[9,0,1],[4,3,2]]

我试过使用set,但只删除了那些相等的列表(我认为它应该起作用,因为集合的定义是没有顺序的)。我访问过的其他问题只有列表完全重复或重复的示例:python:如何删除列表中的重复列表?.目前,输出顺序(对于列表和子列表)不是问题。


(ab)使用列表组件的副作用版本:

1
2
3
4
seen = set()

[x for x in g if frozenset(x) not in seen and not seen.add(frozenset(x))]
Out[4]: [[1, 2, 3], [9, 0, 1], [4, 3, 2]]

对于那些(不像我自己)不喜欢用这种方式使用副作用的人:

1
2
3
4
5
6
7
8
res = []
seen = set()

for x in g:
    x_set = frozenset(x)
    if x_set not in seen:
        res.append(x)
        seen.add(x_set)

向集合中添加frozenset的原因是,只能向set添加哈希对象,而普通set的对象不可哈希。


如果您不关心列表和子列表的顺序(子列表中的所有项都是唯一的):

1
result = set(map(frozenset, g))

如果子列表可能有重复项,如[1, 2, 1, 3],则可以使用tuple(sorted(sublist)),而不是从子列表中删除重复项的frozenset(sublist)

如果要保留子列表的顺序:

1
2
3
4
5
6
7
8
9
def del_dups(seq, key=frozenset):
    seen = {}
    pos = 0
    for item in seq:
        if key(item) not in seen:
            seen[key(item)] = True
            seq[pos] = item
            pos += 1
    del seq[pos:]

例子:

1
del_dups(g, key=lambda x: tuple(sorted(x)))

在python中,从列表中删除重复项的最快算法是什么,以便所有元素在保持顺序的同时都是唯一的?


roippi frozenset提到的使用方法是什么?

1
2
3
>>> g = [list(x) for x in set(frozenset(i) for i in [set(i) for i in g])]

[[0, 9, 1], [1, 2, 3], [2, 3, 4]]


我将把列表中的每个元素转换成一个frozenset(可哈希),然后从中创建一个set来删除重复的:

1
2
3
>>> g = [[1, 2, 3], [3, 2, 1], [1, 3, 2], [9, 0, 1], [4, 3, 2]]
>>> set(map(frozenset, g))
set([frozenset([0, 9, 1]), frozenset([1, 2, 3]), frozenset([2, 3, 4])])

如果需要将元素转换回列表:

1
2
>>> map(list, set(map(frozenset, g)))
[[0, 9, 1], [1, 2, 3], [2, 3, 4]]