我有两组带有列表元素列表的数据。
例如:
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