检查Python中“list type”或“set type”的两个集合之间的相同性



我有两组带有列表元素列表的数据。

例如:

set1 : [[1,2,3], [2,3,4], [1,2]]
set2 : [[1,2], [1,2,3], [2,3,4]]

我试图使用列表集或集合集来使用集合的==运算符,但我有TypeError: unhashable type: 'list'错误。

x = set([[1,2,3],[2,3,4],[1,2]]) <-- Error raised
y = set([[1,2],[1,2,3],[2,3,4]])
x == y

如何检查它们是否由相同的元素组成?

Python的列表是一个不可破解的类型,您可以将它们做成元组:

>>> l1 = [[1,2,3], [2,3,4], [1,2]]
>>> l2 = [[1,2], [1,2,3], [2,3,4]]
>>> set(map(tuple, l1)) 
set([(1, 2), (2, 3, 4), (1, 2, 3)])
>>> set(map(tuple, l2))
set([(1, 2), (2, 3, 4), (1, 2, 3)])
>>> set(map(tuple, l1)) == set(map(tuple, l2))
True

诀窍只是为内部集使用可散列类型。frozenset正好符合要求。

> set1 = [[1,2,3], [4,3,2], [1,2]]
> set2 = [[1,2], [1,2,3], [2,3,4]]
> def nested_set_equality(s1, s2):
      s1 = set(frozenset(e) for e in s1)
      s2 = set(frozenset(e) for e in s2)
      return s1 == s2
> nested_set_equality(set1, set2)
True

如果顺序对内部元素(如[1,2,3](很重要,则tuple是合适的类型,而不是frozenset。如果订单很重要,倍数也很重要([[1,2],[1,2]](,我们可以让它变得更简单:

> sorted(set1) == sorted(set2)

我假设您正在尝试压平列表并从中生成一个集合。

set1 = set([el for sublist in lst1 for el in sublist])
set2 = set([el for sublist in lst2 for el in sublist])
set1 == set2
# True

您还可以定义一个递归函数来压平列表:

def flatten(lst):
    out = list()
    for el in lst:
        if hasattr(el,"__iter__"):
            yield from flatten(el)
        else:
            yield el
set(flatten(lst1)) == set(flatten(lst2))

这将处理n级深度的可迭代项中的任何可迭代项。

#remove duplicate, arrange and convert to string. ie. [1,2] to '1,2'
def conv(l):
    d=list(set(l)) #remove duplicate
    d.sort()       #arrange
    return str(d)[1:-1] # convert to string ie. [1,2] to '1,2'

#now you can use that:ie
s1=[1,2,3],[2,3,4],[1,2]
s2=[1,2], [1,2,3], [2,3,4]
x = set([conv(i) for i in s1]) # <-- No Error raised.. :)
y = set([conv(i) for i in s2])
x == y

最新更新