简体   繁体   中英

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. For example, tuple s are hashable but list s are not, and so your method gives:

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:

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.

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 .

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. You can turn it into tuple as @cᴏʟᴅsᴘᴇᴇᴅ said.

[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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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