views:

273

answers:

6

I have two lists which are guaranteed to be the same length. I want to compare the corresponding values in the list (except the first item) and print out the ones which dont match. The way I am doing it is like this

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]

Is there a better way to do this? (Python 2.x)

+2  A: 

edit: oops, didn't see the "ignore first item" part

from itertools import islice,izip

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

There's a nice class called difflib.SequenceMatcher in the standard library for that.

Eli Bendersky
I get how you would use this to find matching blocks, but not items that are different. Or am I missing something?
RyanWilcox
@RyanWilcox: that should be easy in O(n) once you have the matching blocks
Eli Bendersky
+9  A: 
list1=[1,2,3,4]
list2=[1,5,3,4]
print [(i,j) for i,j in zip(list1,list2) if i!=j]

Output:

[(2, 5)]

Edit: Easily extended to skip n first items (same output):

list1=[1,2,3,4]
list2=[2,5,3,4]
print [(i,j) for i,j in zip(list1,list2)[1:] if i!=j]
mizipzor
tuple unpacking would be faster than indexing. also slicing wouldn't work in py3k
SilentGhost
removed indexing, better? :)
mizipzor
Exactly what I was looking for. Thanks
TP
Consider switching to izip, from itertools, for long lists. It is the iterator version.
Phil H
+1  A: 

Noting the requirement to skip the first line:

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. This uses izip, an iterator (itertools) version of zip, to generate an iterator through pairs of values. This way you don't use up a load of memory generating a complete zipped list.
  2. It steps the both iterator by one to avoid processing the first item, and to avoid having to make the index comparison on every step through the loop. It also makes it cleaner to read.
  3. Finally it steps through each tuple returned from a generator which yields only unequal pairs.
Phil H
+1  A: 

Nobody's mentioned filter:

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
RyanWilcox
+1  A: 

You could use sets:

>>> list1=[1,2,3,4]
>>> list2=[1,5,3,4]
>>> set(list1[1:]).symmetric_difference(list2[1:])
set([2, 5])
Jim
I don't think this quite fits. They want to compare the first element of one list to the first element of the other, and second to second, etc. Since sets are not ordered, I don't think this is right for this problem.
MatrixFrog
Still, sets are an interesting way to deal with this type of problem...
RyanWilcox