Advertisement
Advertisement


How can I compare two lists in python and return matches


Question

I want to take two lists and find the values that appear in both.

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

returnMatches(a, b)

would return [5], for instance.

2009/09/07
1
387
9/7/2009 11:13:45 AM

Accepted Answer

Not the most efficient one, but by far the most obvious way to do it is:

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

if order is significant you can do it with list comprehensions like this:

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

(only works for equal-sized lists, which order-significance implies).

2009/09/07
502
9/7/2009 11:10:46 AM


A quick performance test showing Lutz's solution is the best:

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)

These are the results on my machine:

# 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

Obviously, any artificial performance test should be taken with a grain of salt, but since the set().intersection() answer is at least as fast as the other solutions, and also the most readable, it should be the standard solution for this common problem.

2014/06/05

I prefer the set based answers, but here's one that works anyway

[x for x in a if x in b]

Quick way:

list(set(a).intersection(set(b)))
2009/09/07

The easiest way to do that is to use sets:

>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a) & set(b)
set([5])
2009/09/07

>>> s = ['a','b','c']   
>>> f = ['a','b','d','c']  
>>> ss= set(s)  
>>> fs =set(f)  
>>> print ss.intersection(fs)   
   **set(['a', 'c', 'b'])**  
>>> print ss.union(fs)        
   **set(['a', 'c', 'b', 'd'])**  
>>> print ss.union(fs)  - ss.intersection(fs)   
   **set(['d'])**
2013/05/11

Source: https://stackoverflow.com/questions/1388818
Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Email: [email protected]