比较两个嵌套列表和 return 个共同元素
Compare two nested lists and return common elements
我有两个列表列表如下。
list1 = [["cup", "mug"], ["happy", "joy", "smile"], ["trees", "bushes"]]
list2 = [["cat", "dog"], ["trees", "bushes"], ["cup", "mug"]]
现在,我想return两个列表中的共同元素。
Common elements = [["trees", "bushes"], ["cup", "mug"]]
我尝试了以下代码:
print(list(set(list1).intersection(list2)))
然而,它不起作用。有什么建议吗?
您可能正在寻找:
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
s 是可散列的,但 list
s 不是,所以你的方法给出:
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
是不可变的容器。
更简单的方法是
[elem for elem in list1 if elem in list2]
你可以获得
>>> [elem for elem in list1 if elem in list2]
[['cup', 'mug'], ['trees', 'bushes']]
感谢 Python 支持 in
运算符用于 list
。
你的问题的原因是,list
是可变的,所以它不能被散列,导致列表的列表不能转换为集合。正如@cᴏʟᴅsᴘᴇᴇᴅ所说,你可以把它变成tuple
。
[list(x) for x in set(map(tuple, list1)).intersection(map(tuple, list2))]
这两种方法都可以,但是由于内部算法不同,性能上会有差异。但是我觉得很难说哪个更快,可能要看你的数据了。
短版本的一个好处是,输出数据的顺序与list1
相同,如果您需要此功能。
我有两个列表列表如下。
list1 = [["cup", "mug"], ["happy", "joy", "smile"], ["trees", "bushes"]]
list2 = [["cat", "dog"], ["trees", "bushes"], ["cup", "mug"]]
现在,我想return两个列表中的共同元素。
Common elements = [["trees", "bushes"], ["cup", "mug"]]
我尝试了以下代码:
print(list(set(list1).intersection(list2)))
然而,它不起作用。有什么建议吗?
您可能正在寻找:
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
s 是可散列的,但 list
s 不是,所以你的方法给出:
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
是不可变的容器。
更简单的方法是
[elem for elem in list1 if elem in list2]
你可以获得
>>> [elem for elem in list1 if elem in list2]
[['cup', 'mug'], ['trees', 'bushes']]
感谢 Python 支持 in
运算符用于 list
。
你的问题的原因是,list
是可变的,所以它不能被散列,导致列表的列表不能转换为集合。正如@cᴏʟᴅsᴘᴇᴇᴅ所说,你可以把它变成tuple
。
[list(x) for x in set(map(tuple, list1)).intersection(map(tuple, list2))]
这两种方法都可以,但是由于内部算法不同,性能上会有差异。但是我觉得很难说哪个更快,可能要看你的数据了。
短版本的一个好处是,输出数据的顺序与list1
相同,如果您需要此功能。