Python中两个列表的有序交集

Python中两个列表的有序交集,python,list,Python,List,我知道在Python中,如果我有: list_1 = [1,2,3] list_2 = [2,3,4] 我可以执行以下操作来查找两者之间的交点: list(set(list_1) & set(list_2)) # = [2,3] 但这种方法有一个问题:集合不能像列表那样维持秩序。如果我真的有: list_1 = [3,2,1] list_2 = [2,3,4] 我得到: list(set(list_1) & set(list_2)) # = [2,3] 尽管我更喜欢第一个

我知道在Python中,如果我有:

list_1 = [1,2,3]
list_2 = [2,3,4]
我可以执行以下操作来查找两者之间的交点:

list(set(list_1) & set(list_2))
# = [2,3]
但这种方法有一个问题:集合不能像列表那样维持秩序。如果我真的有:

list_1 = [3,2,1]
list_2 = [2,3,4]
我得到:

list(set(list_1) & set(list_2))
# = [2,3]
尽管我更喜欢第一个列表中的顺序,即:

# = [3,2]
是否有其他交叉点技术可以使生成的“交叉点集”与第一个列表的顺序相同

set_2 = frozenset(list_2)
intersection = [x for x in list_1 if x in set_2]

set
frozenset
一样,我越来越习惯于在我不打算改变数据的情况下使用不可变类。要点是,为了维护顺序,您需要按照您想要维护的顺序遍历列表,但您不希望具有原始方法的n*m复杂性:
[x代表列表中的x,如果列表中的x\u 2中的x]
。检查
集合
或类似基于散列的类型中的成员资格大致为O(1),而列表中的成员资格检查为O(n)。

使用列表的索引方法作为排序标准:

l1 = [3, 2, 1]
l2 = [2, 3, 4]
sorted(set(l1) & set(l2), key = l1.index)
输出:


在我的例子中,这种天真的方法已经足够好了(我的列表最大长度为10左右);它工作得很好,读起来更清晰。谢谢。相关的:例如,或者——两者都保留顺序这似乎也是一个很好的解决方案。。。但我已经实现了Peter的解决方案,而且它是有效的,所以我不想与成功混为一谈:-)坏主意。此解决方案将为O(n^2),因为交叉点中的每个元素都必须搜索列表才能找到索引。彼得的答案是O(n)。@Duncan是的,几乎正确。事实上,这取决于交叉点的大小和列表的长度。但是,答案仍然提供了一种替代Peter方法的方法,这种方法在其他情况下可能有用,例如,当订单由第三个列表获得时。对于小列表来说,复杂性并不重要,因此,答案肯定是有用的,不应该被否决……如果顺序取决于第三个列表,那么您只需使用Peter DeGlopper的答案,但用两个列表的组合替换
set_2
set_2=set(l1)和set(l2)
然后
intersection=[x代表列表_3中的x,如果set_2中的x]
仍然不需要进行线性搜索。
[3, 2]