Python:从有序列表中删除不在无序列表中的条目

4

我有两个列表:

ordered = ['salat', 'baguette', 'burger', 'pizza']
unordered = ['pizza', 'burger']

现在我想要从有序列表中移除所有不在无序列表中的条目,同时保持排序。请问如何做到这点?

1
你是否关心有序的顺序保留? - DSM
是的,我需要排序。 - Martin
你能给出无序和有序的示例大小以及重叠部分有多大吗?无序中可能还有其他项目吗? - Johan Lundberg
这些列表的项数不超过20个,且重叠度约为80%。 - Martin
3个回答

9
ordered = [item for item in ordered if item in unordered]

这种方法使用Python的列表推导式基于旧列表创建一个新列表。
对于大量数据,将无序列表先转换为集合,如评论中所建议的那样,可以显著提高性能,例如:
unordered = set(unordered)

基准测试!

有序列表: 5000个项目,无序列表: 1000个项目
没有使用set的时间为0.09561秒
使用了set后的时间为0.00042秒

对于10/2个项目,时间几乎相同,因此最好始终使用set,无论数据大小如何。


3
这可能是我会做的事情,尽管如果列表很长,我可能会制作一个无序集合版本以加快成员测试的速度。 - DSM
+1 这是最惯用的解决方案。除非性能成为问题,否则我不会尝试加速它。 - Todd Owen
unordered转换为set可能会提高运行时效率。 - inspectorG4dget
@DSM:啊!抱歉,可能是浏览器缓存/刷新问题。不过,为什么对于较小的数据集使用列表(而不是集合)会更快呢?哈希函数真的那么耗时吗?还是还有其他我没注意到的原因? - inspectorG4dget
1
在数字4和2的情况下(我得到的timeit结果为0.473秒,没有设置为0.696),集合构建开销太大了。当然,在这种微不足道的情况下,它所需的时间非常少,几乎没有必要担心性能问题。 - DSM

2
最好使用集合来测试成员资格,像这样:

ordered = ['salat', 'baguette', 'burger', 'pizza']
unordered = ['pizza', 'burger']

unord = set(unordered)
ordered = [e for e in ordered if e in unord]

0

类似这样的:

ordered = list(filter(lambda x: x not in unordered, ordered))

如果使用 Python <3,则list函数是不必要的。


1
我不得不说,这相当丑陋。 - Oleh Prypin
是的,你说得对。在看到你的答案之前,我没有想到列表推导式。 - Anthony Nguyen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接