2010-03-05 12 views
15

Tengo dos listas que se garantiza que tienen la misma longitud. Quiero comparar los valores correspondientes en la lista (excepto el primer elemento) e imprimir los que no coinciden. La forma en que lo estoy haciendo es asíManera pitónica de comparar dos listas e imprimir las diferencias

i = len(list1) 
if i == 1: 
    print 'Nothing to compare' 
else: 
    for i in range(i): 
     if not (i == 0): 
      if list1[i] != list2[i]: 
       print list1[i] 
       print list2[i] 

¿Hay una forma mejor de hacerlo? (Python 2.x)

+2

La programación funcional a la rescate: mira en el mapa y zip! – mjv

Respuesta

20
list1=[1,2,3,4] 
list2=[1,5,3,4] 
print [(i,j) for i,j in zip(list1,list2) if i!=j] 

de salida:

[(2, 5)] 

Editar: extender fácilmente a saltar n primeros elementos (misma salida):

list1=[1,2,3,4] 
list2=[2,5,3,4] 
print [(i,j) for i,j in zip(list1,list2)[1:] if i!=j] 
+0

desempaquetar tuplas sería más rápido que indexar. Además, el corte no funcionaría en py3k – SilentGhost

+0

eliminado la indexación, ¿es mejor? :) – Mizipzor

+1

Exactamente lo que estaba buscando. Gracias – randomThought

2

edición: ¡Uy, no vio la parte de "ignorar primer artículo"

from itertools import islice,izip 

for a,b in islice(izip(list1,list2),1,None): 
    if a != b: 
     print a, b 
2

Hay una clase agradable llamada difflib.SequenceMatcher en la biblioteca estándar para eso.

+0

Obtengo cómo usaría esto para encontrar bloques coincidentes, pero no elementos que son diferentes. ¿O me estoy perdiendo algo? – RyanWilcox

+0

@RyanWilcox: eso debería ser fácil en O (n) una vez que tenga los bloques coincidentes –

2

Observando el requisito para omitir la primera línea:

from itertools import izip 
both = izip(list1,list2) 
both.next() #skip the first 
for p in (p for p in both if p[0]!=p[1]): 
    print pair 
  1. Esto usa izip, un iterador (itertools) versión de zip, para generar un iterador a través de pares de valores. De esta forma, no consume una carga de memoria generando una lista comprimida completa.
  2. Ejecuta el iterador both por uno para evitar el procesamiento del primer elemento y para evitar tener que realizar la comparación del índice en cada paso del ciclo. También lo hace más limpio para leer.
  3. Finalmente pasa por cada tupla devuelta desde un generador que produce solo pares desiguales. Filtro
5

Nadie ha mencionado:

a = [1, 2, 3] 
b = [42, 3, 4] 

aToCompare = a[1:] 
bToCompare = b[1:] 

c = filter(lambda x: (not(x in aToCompare)), bToCompare) 
print c 
2

Usted podría utilizar conjuntos:

>>> list1=[1,2,3,4] 
>>> list2=[1,5,3,4] 
>>> set(list1[1:]).symmetric_difference(list2[1:]) 
set([2, 5]) 
+0

No creo que esto encaje bien. Quieren comparar el primer elemento de una lista con el primer elemento de la otra, y de segundo a segundo, etc.Como los conjuntos no están ordenados, no creo que esto sea correcto para este problema. – MatrixFrog

+0

Aún así, los juegos son una forma interesante de lidiar con este tipo de problema ... – RyanWilcox

0

Suponiendo que los dos tipos son iguales y tienen la misma longitud:

list1=[1,2,3,4] 
list2=[1,5,3,4] 
print list1==list2 
Cuestiones relacionadas