如何在Python中比较两个列表并返回匹配项

535 投票
21 回答
1540594 浏览
提问于 2025-04-15 14:07

我想把两个列表拿来,找出同时出现在这两个列表里的值。

a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]

returnMatches(a, b)

比如说,这样做会返回 [5]

21 个回答

139

这里有一个简单的性能测试,显示了Lutz的解决方案是最好的:

import time

def speed_test(func):
    def wrapper(*args, **kwargs):
        t1 = time.time()
        for x in xrange(5000):
            results = func(*args, **kwargs)
        t2 = time.time()
        print '%s took %0.3f ms' % (func.func_name, (t2-t1)*1000.0)
        return results
    return wrapper

@speed_test
def compare_bitwise(x, y):
    set_x = frozenset(x)
    set_y = frozenset(y)
    return set_x & set_y

@speed_test
def compare_listcomp(x, y):
    return [i for i, j in zip(x, y) if i == j]

@speed_test
def compare_intersect(x, y):
    return frozenset(x).intersection(y)

# Comparing short lists
a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]
compare_bitwise(a, b)
compare_listcomp(a, b)
compare_intersect(a, b)

# Comparing longer lists
import random
a = random.sample(xrange(100000), 10000)
b = random.sample(xrange(100000), 10000)
compare_bitwise(a, b)
compare_listcomp(a, b)
compare_intersect(a, b)

这是我机器上的测试结果:

# Short list:
compare_bitwise took 10.145 ms
compare_listcomp took 11.157 ms
compare_intersect took 7.461 ms

# Long list:
compare_bitwise took 11203.709 ms
compare_listcomp took 17361.736 ms
compare_intersect took 6833.768 ms

显然,任何人为的性能测试都要谨慎看待,但因为使用 set().intersection() 的方法至少和其他解决方案一样快,而且也最容易理解,所以它应该成为这个常见问题的标准解决方案。

563

使用 set.intersection() 方法,它既快速又容易理解。

>>> set(a).intersection(b)
set([5])
691

这不是最有效的方法,但绝对是最简单明了的做法:

>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a) & set(b)
{5}

如果顺序很重要,你可以用列表推导式这样做:

>>> [i for i, j in zip(a, b) if i == j]
[5]

(这只适用于大小相等的列表,因为顺序重要的情况下,列表的大小必须相同)。

撰写回答