2011-01-23 15 views
5
a = [1, 2, 9, 5, 1] 
b = [9, 8, 7, 6, 5] 

Quiero contar el número de duplicados entre las dos listas. Entonces, usando lo anterior, quiero devolver un recuento de 2 porque 9 y 5 son comunes a ambas listas.Contar duplicados entre 2 listas

Intenté algo como esto pero no funcionó del todo.

def filter_(x, y): 
    count = 0 
    for num in y: 
     if num in x: 
      count += 1 
      return count 
+0

Observe que una vez que funciona (dedent el 'return' dos veces), tiene' O (n * m) 'complexit, es decir, escala bastante horriblemente. – delnan

+0

@delnan gracias por la propina. así que usar escalas de intersección mejor. – super9

+0

Sí. En realidad puede hacerlo aún mejor, pero eso requiere más de una línea de código (la idea es que solo necesita un conjunto de la primera lista, luego iterar sobre el segundo y conservar los elementos que están en el conjunto; guarda la creación de un segundo conjunto). – delnan

Respuesta

16

más corto y mejor manera:

>>> a = [1, 2, 9, 5, 1] 
>>> b = [9, 8, 7, 6, 5] 
>>> len(set(a) & set(b))  # & is intersection - elements common to both 
2 

Por qué su código no funciona:

>>> def filter_(x, y): 
...  count = 0 
...  for num in y: 
...    if num in x: 
...      count += 1 
...  return count 
... 
>>> filter_(a, b) 
2 

Su return count fue dentro del bucle y se volvió sin ejecución ser completa.

+0

Cristo, sigo cometiendo el mismo error. ¡Gracias! – super9

8

Puede utilizar set.intersection:

>>> set(a).intersection(set(b)) # or just: set(a).intersection(b) 
set([9, 5]) 

O, para la longitud de la intersección:

>>> len(set(a).intersection(set(b))) 
2 

O, más concisa:

>>> len(set(a) & set(b)) 
2 
+0

No quiero 9,5. Quiero un recuento de 2. – super9

+0

No es necesario crear explícitamente un conjunto de la lista b, el método de intersección establecido admite listas como entradas. – Spaceghost

3

convertirlos a set sy cuente la intersección.

len(set(a).intersection(set(b))) 
4

Si desea contar entradas multiplicitarias, las soluciones basadas en conjuntos fallarán; necesitará algo así como

from collections import Counter 

def numDups(a, b): 
    if len(a)>len(b): 
     a,b = b,a 

    a_count = Counter(a) 
    b_count = Counter(b) 

    return sum(min(b_count[ak], av) for ak,av in a_count.iteritems()) 

continuación

numDups([1,1,2,3], [1,1,1,1,1]) 

rendimientos 2. El tiempo de ejecución en este escalas como O (n + m).

Además, su solución inicial

for num in y: 
    if num in x: 
     count += 1 

está mal - se aplica a [1,2,3,3] y [1,1,1,1,1,3], su código devolverá o bien 3 o 6, ninguno de los cuales es correcto (la respuesta debería ser 2).

+0

esta solución es mejor porque también cuenta los duplicados, gracias :) – Zavael

Cuestiones relacionadas