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

时间:2017-09-23 05:01:55

标签: python list set comparison set-intersection

我有两个列表列表如下。

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

现在,我想在两个列表中返回常用元素。

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

我尝试了以下代码:

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

然而,它不起作用。有什么建议吗?

2 个答案:

答案 0 :(得分:1)

你可能正在寻找:

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

您还可以使用&运算符(集合的交集运算符):

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

您的代码不起作用的原因是因为您没有将每个单独的列表元素转换为set可以散列的内容。例如,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'

但是,将每个元素转换为tuple可以对它们进行哈希处理:

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

原因是tuple是不可变的容器。

答案 1 :(得分:0)

更简单的方法是

[elem for elem in list1 if elem in list2]

你可以得到

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

感谢Python支持in的{​​{1}}运算符。

你的问题的原因是,list是可变的,因此它不能被清除,导致列表列表无法转换为集合。你可以把它变成list,因为@cᴏʟᴅsᴘᴇᴇᴅ说。

tuple

这两种方法都有效,但由于内部算法不同,它们在性能上存在差异。但我认为很难说哪个更快,可能取决于你的数据。

短版本的一个优点是,如果您需要此功能,输出数据将与[list(x) for x in set(map(tuple, list1)).intersection(map(tuple, list2))] 具有相同的顺序。