2013-02-16 11 views

risposta

16

Il modo più semplice per farlo è quello di utilizzare the sum() built-in e un generator expression:

def differences(a, b): 
    if len(a) != len(b): 
     raise ValueError("Lists of different length.") 
    return sum(i != j for i, j in zip(a, b)) 

Abbiamo un ciclo sulle liste insieme usando zip() e poi confrontarli. Come True == 1 e False == 0, sommiamo questo per ottenere il numero di differenze. Un'altra opzione sarebbe quella di utilizzare la parte condizionale dell'espressione generatore:

sum(1 for i, j in zip(a, b) if i != j) 

non posso davvero dire che mi sento uno è più leggibile rispetto agli altri, e dubito ci sarà una differenza di prestazioni.

+0

preferisco l'esplicito '1 per i ', al posto del booleano implicito (basandosi sul fatto che è un' int'), ma in ogni caso +1 (a patto che sia esplicito il controllo della lunghezza) –

+0

@JonClements Sono d'accordo, eppure poi la parte importante (il confronto) viene spinto a la fine dell'espressione, che sembra imbarazzante. Continuo a cambiare idea su cosa preferisco. –

-1

È possibile utilizzare sets. Inserisci entrambi in un set, quindi trova la differenza tra i due. Ad esempio:

>>> a = [1,3,5,7,9] 
>>> b = [1,2,5,7,2] 
>>> len(set(a) - set(b)) 
2 

Questo potrebbe essere racchiuso in una funzione per verificare prima le differenze di lunghezza.

+2

Questo non funzionerà se ci sono elementi ripetuti e non tiene conto dell'ordine. 'difference ([1, 3, 5, 7, 9], [9, 7, 5, 3, 1])' sarebbe '0' rispetto a' 4'. L'esempio dell'OP considera "3" diverso, nonostante sia presente in entrambe le liste (vale a dire, la posizione è importante). Ciò ignora anche la possibilità che le liste abbiano lunghezze diverse, come menzionato nella domanda. –

+0

Ah sì, ho perso l'ultimo 3 e ne ho usato 2 nel mio esempio. Colpa mia! Ho detto che una funzione potrebbe essere utilizzata per verificare le differenze, come per il codice di esempio. – user2079098

1

soluzione One-liner che produce anche un errore se la lunghezza non è uguale:

>>> sum(map(lambda x,y: bool(x-y),a,b)) 
2 

Ora provare l'input di lunghezza diversa:

>>> sum(map(lambda x,y: bool(x-y),[1,2],[1])) 
TypeError 

Come funziona: bool (x, y) restituisce True se gli elementi sono diversi. Quindi mappiamo questa funzione in 2 elenchi e otteniamo l'elenco [Falso, Vero, Falso, Vero, Falso].
Se mettiamo nella mappa delle funzioni() gli elenchi di diversa lunghezza, si ottiene il TypeError

Infine, la funzione sum() di questa lista booleana dà 2.

+0

Nota che 'map()' e 'lambda' sono generalmente più lenti e meno leggibili di un'espressione compilazione/generatore di lista, e questo funzionerà solo per i numeri. –

+0

sì, sono più lenti, ma il codice è molto più breve, dipende da cosa è necessario (esagerando, c'è bisogno di velocità, non usare python :)). Ciò che è più leggibile è una questione molto soggettiva. Hai ragione che questo non funziona su tipi in cui l'operazione "-" non è definita. –

+0

Grazie per un'altra soluzione.Preferisco la soluzione di @ Lattyware perché personalmente ritengo che sia più leggibile. Non ho familiarità con la funzione 'lambda'. Anche con la sua soluzione posso definire il messaggio di errore, quindi so quale errore ho ricevuto. – LWZ

Problemi correlati