按等效类将列表中的元素分组

时间:2018-09-20 20:08:34

标签: python-3.x list for-loop set

在尝试通过应用集合从一个列表中创建新列表时遇到问题。

假设我有以下列表:

L=[[(a),(b),(c)],[(b),(c),(a)],[(a),(c),(b)],[(a),(d),(b)]]

我希望仅从L中具有相同元素的列表中创建一个列表。我们可以清楚地看到:

[(a),(b),(c)], [(b),(c),(a)] and [(a),(c),(b)] 

当视为集合时,它们是相同的,因为它们都共享元素(a),(b)和(c)。

因此,如果我希望应用此规则从L创建新列表:

然后,我需要两个新列表,即:

[(a),(b),(c)] and [(a),(d),(b)]

因为

[(a),(d),(b)] 

看成一组与其他列表不同。

什么是实现此目的的最佳方法?我知道如何将L内的一个元素转换为一个集合,但是如果我想应用此规则以便仅创建两个独立的列表,该怎么办?

3 个答案:

答案 0 :(得分:2)

set中的frozenset个可以大致为您提供所需的东西(尽管它不会保留顺序):

unique_sets = {frozenset(lst) for lst in L}

尽管在set转换中丢失了订单,但是转换回list中的list很简单:

unique_lists = [list(s) for s in unique_sets]

答案 1 :(得分:1)

您可以在frozenset个中创建一个set,仅获得唯一的集合,而忽略订单的数量和数量:

set(map(frozenset, L))
# {frozenset({'a', 'd', 'b'}), frozenset({'a', 'c', 'b'})}

然后将它们转换回列表很简单:

list(map(list, set(map(frozenset, L))))
# [['a', 'd', 'b'], ['a', 'c', 'b']]

答案 2 :(得分:1)

如果您愿意为hash写一个set方法,那么您可以这样做:

import itertools
[k for k, g in itertools.groupby(sorted([set(y) for y in x], key = your_hash))]