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

Voglio contare il numero di duplicati tra le due liste. Quindi, utilizzando quanto sopra, voglio restituire un conteggio di 2 perché 9 e 5 sono comuni a entrambe le liste.Conta duplicati tra 2 elenchi

Ho provato qualcosa del genere ma non ha funzionato.

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

Si noti che una volta che funziona (dedurre il 'return' due volte), ha' O (n * m) 'complexit, vale a dire scale piuttosto orribili. – delnan

+0

@delnan grazie per il suggerimento. quindi usare l'intersezione si adatta meglio. – super9

+0

Sì. In realtà puoi fare anche meglio, ma questo richiede più di una riga di codice (l'idea è che hai solo bisogno di un set del primo elenco, quindi scorrere il secondo e mantenere gli elementi nel set - salva la creazione di un secondo impostato). – delnan

risposta

16

Shorter modo e meglio:

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

Perché il codice non funziona:

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

tuo return count era all'interno del ciclo for e restituito senza esecuzione essere completo.

+0

Cristo, continuo a fare lo stesso errore. Grazie! – super9

8

È possibile utilizzare set.intersection:

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

Oppure, per la lunghezza di intersezione:

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

Oppure, più concisa:

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

Non voglio 9,5. Voglio un conteggio di 2. – super9

+0

Non è necessario creare un set in modo esplicito dall'elenco b, il metodo di intersezione impostato supporta gli elenchi come input. – Spaceghost

3

convertirli in set s e conta l'intersezione.

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

Se si desidera contare voci multiple, le soluzioni basate su insuccessi non riusciranno; avrete bisogno di qualcosa di simile a

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()) 

poi

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

rendimenti 2. Il tempo di esecuzione su questo scale come O (n + m).

Inoltre, la soluzione iniziale

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

è sbagliato - applicato a [1,2,3,3] e [1,1,1,1,1,3], il codice restituirà sia 3 o 6, di cui è corretto (la risposta dovrebbe essere 2).

+0

questa soluzione è migliore perché conta anche i duplicati, grazie :) – Zavael

Problemi correlati