¿Cómo puedo comparar dos listas en Python y devolver coincidencias [duplicado]

Resuelto tehryan asked hace 15 años • 21 respuestas

Quiero tomar dos listas y encontrar los valores que aparecen en ambas.

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

returnMatches(a, b)

volvería [5], por ejemplo.

tehryan avatar Sep 07 '09 18:09 tehryan
Aceptado

No es la más eficiente, pero sí la forma más obvia de hacerlo:

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

Si el orden es importante, puede hacerlo con listas por comprensión como esta:

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

(solo funciona para listas del mismo tamaño, lo que implica orden significativo).

SilentGhost avatar Sep 07 '2009 11:09 SilentGhost

Utilice set.intersection() , es rápido y legible.

>>> set(a).intersection(b)
set([5])
 avatar Sep 07 '2009 11:09

Una prueba de rendimiento rápida que muestra que la solución de Lutz es la mejor:

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)

Estos son los resultados en mi máquina:

# 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

Obviamente, cualquier prueba de rendimiento artificial debe tomarse con cautela, pero dado que la set().intersection()respuesta es al menos tan rápida como las otras soluciones, y también la más legible, debería ser la solución estándar para este problema común.

Joshmaker avatar Jun 03 '2012 17:06 Joshmaker

Prefiero las respuestas basadas en conjuntos, pero aquí hay una que funciona de todos modos

[x for x in a if x in b]
SingleNegationElimination avatar Sep 30 '2010 20:09 SingleNegationElimination

De manera rápida:

list(set(a).intersection(set(b)))
DisplacedAussie avatar Sep 07 '2009 11:09 DisplacedAussie