简体   繁体   English

比较两个嵌套列表并返回公共元素

[英]Compare two nested lists and return common elements

I have two list of lists as follows. 我有两个列表如下。

list1 = [["cup", "mug"], ["happy", "joy", "smile"], ["trees", "bushes"]]
list2 = [["cat", "dog"], ["trees", "bushes"], ["cup", "mug"]]

Now, I want to return common elements in the two lists. 现在,我想返回两个列表中的公共元素。

Common elements = [["trees", "bushes"], ["cup", "mug"]]

I tried the following code: 我尝试了以下代码:

print(list(set(list1).intersection(list2)))

However, it does not work. 但是,它不起作用。 Any suggestions? 有什么建议么?

You're probably looking for: 您可能正在寻找:

In [773]: [list(x) for x in set(map(tuple, list1)).intersection(map(tuple, list2))]
Out[773]: [['trees', 'bushes'], ['cup', 'mug']]

You could also use the & operator (the intersection operator for sets): 您还可以使用&运算符(集合的交集运算符):

In [778]: [list(x) for x in set(map(tuple, list1)) & set(map(tuple, list2))]
Out[778]: [['trees', 'bushes'], ['cup', 'mug']]

The reason your code does not work is because you're not converting each individual list element into something that a set can hash. 您的代码不起作用的原因是,您没有将每个单独的列表元素都转换为set可以哈希的内容。 For example, tuple s are hashable but list s are not, and so your method gives: 例如, tuple是可哈希的,而list则不是,因此您的方法给出:

In [774]: set(list1)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-774-a09f7eaac729> in <module>()
----> 1 set(list1)

TypeError: unhashable type: 'list'

However, converting each element to a tuple allows them to be hashed: 但是,将每个元素转换为tuple可以对其进行哈希处理:

In [775]: set(map(tuple, list1))
Out[775]: {('cup', 'mug'), ('happy', 'joy', 'smile'), ('trees', 'bushes')}

The reason for this is that tuple s are immutable containers. 原因是tuple是不可变的容器。

A simpler way is 一个更简单的方法是

[elem for elem in list1 if elem in list2]

you can get 你可以得到

>>> [elem for elem in list1 if elem in list2]
[['cup', 'mug'], ['trees', 'bushes']]

thanks to Python supports in operator for a list . 由于Python支持in运营商的list

The reason of your problem is that, list is mutable, so that it's cannot be hashable, causes list of lists cannot be converted to a set. 您的问题的原因是, list是可变的,因此它不能是可哈希的,导致列表列表不能转换为集合。 You can turn it into tuple as @cᴏʟᴅsᴘᴇᴇᴅ said. 您可以按照@cᴏʟᴅsᴘᴇᴇᴅ所说将其转换为tuple

[list(x) for x in set(map(tuple, list1)).intersection(map(tuple, list2))]

These two methods both works, but they have differences in performance, due to different algorithms inside. 这两种方法都可以使用,但是由于内部算法不同,它们的性能有所不同。 But I think it's hard to say which is faster, it may depends on your data. 但是我认为很难说哪个更快,这可能取决于您的数据。

The certain advantage of the short version is that, the output data will have the same order as list1 , if you need this feature. 简短版本的一定优势是,如果需要此功能,则输出数据的顺序将与list1相同。

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

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