简体   繁体   English

如何在Python中找到包含列表的两个列表之间的区别?

[英]How to find the difference between two lists that contain lists in Python?

If we have 如果我们有

X1=[[a,b,c],[a,e,t],[a,b,c]] 

and

X2=[[a,b,c]] 

I want to find the difference between X1 and X2 which is: 我想找到X1和X2之间的区别是:

X3=X1-X2=[[a,b,c],[a,e,t]].

So my output should contain two lists not one as I only want to remove one [a,b,c] not both. 所以我的输出应包含两个列表而不是一个列表,因为我只想删除一个[a,b,c]而不是两个。

I am doing it in this way but I get error: 我以这种方式这样做,但出现错误:

s = set(X2)
X3 = [x for x in X1 if x not in s]

The error I get is this: 我得到的错误是这样的:

unhashable type: 'list'

I get this error when the program get to this point: 当程序到达这一点时,我得到此错误:

s = set(X2)

So, X3 = [a,e,t] , right? 那么X3 = [a,e,t] ,对吗?

There is no need to convert it to set. 无需将其转换为set。 You can do this: 你可以这样做:

result = [x for x in X1 if x not in X2] . result = [x for x in X1 if x not in X2]

lists are unhashable so they cannot be members of a set . 列表不可散列,因此不能成为set成员。 You can convert the inner lists into a frozenset , so two sublists with the same items but different ordering are still considered same and then use a Counter to find the difference between both lists: 您可以将内部列表转换为frozenset ,因此frozenset具有相同项目但顺序不同的两个子列表视为相同,然后使用Counter查找两个列表之间的差异

from collections import Counter

X3 = Counter([frozenset(i) for i in X1]) - Counter([frozenset(i) for i in X2])
print(X3)
# Counter({frozenset({'c', 'a', 'b'}): 1, frozenset({'e', 'a', 't'}): 1})

print(X3.keys())
# [frozenset({'e', 't', 'a'}), frozenset({'c', 'b', 'a'})]

A Counter is a subclass of a dict , so you can return the difference as a list by using .keys() : Counterdict的子类,因此您可以使用.keys()将差异作为列表返回:

print(X3.keys()) # or print(list(X3.keys())) in Python 3.x
# [frozenset({'e', 't', 'a'}), frozenset({'c', 'b', 'a'})]

If you need to keep your inner list s, you can replace the frozenset with lists by doing: 如果您需要保留内部list s,则可以通过执行以下frozenset用列表替换frozenset

X3 = [list(i) for i in X3.keys()]

print(X3)
# [['a', 't', 'e'], ['c', 'a', 'b']]

As the error states, lists are unhashable (because they're mutable). 由于错误状态,列表是不可散列的(因为它们是可变的)。 Convert your list of lists into a list of tuples, which are hashable: 将列表列表转换为可哈希的元组列表:

>>> hash((1, 2, 3))
2528502973977326415
>>> hash([1, 2, 3])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

In your case, you could do: 就您而言,您可以执行以下操作:

s = set(map(tuple, X2))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM