Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python—两个列表的交集_Python_List_Intersection - Fatal编程技术网

Python—两个列表的交集

Python—两个列表的交集,python,list,intersection,Python,List,Intersection,这是我的两份清单 k = [[1, 2], [4], [5, 6, 2], [1, 2], [3], [4], [5,9]] kDash = [[1, 2], [4], [5, 6, 2], [1, 2], [3], [4], [5,6], [1,2]] 我的输出应该如下 [[1, 2], [4], [5, 6, 2], [1, 2], [3], [4]] 如何获得此输出 提前谢谢您必须将列表转换为元组列表,然后使用交集。请注意,下面的解决方案可能会有不同顺序的元素,并且显然不会有重复的元素

这是我的两份清单

k = [[1, 2], [4], [5, 6, 2], [1, 2], [3], [4], [5,9]]
kDash = [[1, 2], [4], [5, 6, 2], [1, 2], [3], [4], [5,6], [1,2]]
我的输出应该如下

[[1, 2], [4], [5, 6, 2], [1, 2], [3], [4]]
如何获得此输出


提前谢谢

您必须将列表转换为元组列表,然后使用交集。请注意,下面的解决方案可能会有不同顺序的元素,并且显然不会有重复的元素,因为我使用的是set

In [1]: l1 = [[1, 2], [4], [5, 6, 2], [1, 2], [3], [4], [5,9]]

In [2]: l2 = [[1, 2], [4], [5, 6, 2], [1, 2], [3], [4], [5,6], [1,2]]

In [3]: [list(x) for x in set(tuple(x) for x in l1).intersection(set(tuple(x) for x in l2))]
Out[3]: [[1, 2], [5, 6, 2], [3], [4]]
您也可以将交叉点保存在变量中,并获取最终列表(如果顺序相同,则需要重复):

In [4]: intersection = set(tuple(x) for x in l1).intersection(set(tuple(x) for x in l2))

In [5]: [x for x in l1 if tuple(x) in intersection]
Out[5]: [[1, 2], [4], [5, 6, 2], [1, 2], [3], [4]]
还有十字路口,以防万一,如果你有兴趣的话

In [6]: print intersection
set([(1, 2), (5, 6, 2), (3,), (4,)])

这对于大型列表非常有效,但如果列表很小,请使用@timegb探索另一种解决方案(对于较长的列表,其解决方案将非常不理想)

由于输出列表中有重复的元素,因此您似乎并不真正想要一个经典的交集。一个基本的列表理解将做一切

>>> k = [[1, 2], [4], [5, 6, 2], [1, 2], [3], [4], [5,9]]
>>> kDash = [[1, 2], [4], [5, 6, 2], [1, 2], [3], [4], [5,6], [1,2]]
>>> [x for x in k if x in kDash]
[[1, 2], [4], [5, 6, 2], [1, 2], [3], [4]]
对于大型列表,我们希望获得调用O(1)而不是O(n)所需的时间:


编写交叉点的更简洁的方法是

{tuple(x) for x in l1} & {tuple(x) for x in l2}
一个好的选择是

{tuple(x) for x in l1}.intersection(map(tuple, l2))

尽管这里写的是更优雅的解决方案,但这里还有另一个

def foo(L1,L2):
    res=[]
    for lst in L1:
        if lst in L2:
            res.append(lst)
    return res

我发现的问题是无法将列表列表转换为集合,如果可能的话,可以很容易地进行此交叉。请解释获得输出的逻辑。您能解释一下为什么
[5,6]
[5,9]
位于交叉点吗?很抱歉,这是我的错误,我会更正它,如果需要删除重复元素,可以查看;)这将比
设置
交叉点方法慢得多。缩放类似于
O(n²k)
,其中
n
是子列表的数量,
k
是每个子列表的平均长度。我刚刚意识到OPs输出列表有重复的元素。因此,除非规格发生变化,否则列表comp是一种方法。我认为您的优化版本可能正在重新创建
集合
,以便在每个循环上进行测试,因此它实际上并没有解决
O(n)
问题…@ShadowRanger holy cow您是对的,我刚刚用
set
的一个子类测试了这一点,它在调用
\uuuu init\uuuu
时打印一些东西。我将编辑我的答案。
def foo(L1,L2):
    res=[]
    for lst in L1:
        if lst in L2:
            res.append(lst)
    return res