16

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)

randomThought
  • 6,203
  • 15
  • 56
  • 72

7 Answers7

21
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
  • 51,151
  • 22
  • 97
  • 138
  • tuple unpacking would be faster than indexing. also slicing wouldn't work in py3k – SilentGhost Mar 05 '10 at 16:09
  • Consider switching to izip, from itertools, for long lists. It is the iterator version. – Phil H Mar 09 '10 at 15:18
  • 1
    @ mizipzor This doesn't work if the lengths of lists are different. zip would truncate the extra elements. Eg: `list1=[1,2,3]` `list2=[1,2]` mismatches should return `[3,None]` instead of `[]` – balki Mar 13 '12 at 05:32
  • @balki: in the case of lists with different lengths, the shortest one should be padded with None. – Mizipzor Mar 14 '12 at 16:07
5

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
  • 13,890
  • 1
  • 36
  • 60
2

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
  • 89,068
  • 17
  • 119
  • 137
2

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

Eli Bendersky
  • 263,248
  • 89
  • 350
  • 412
2

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
  • 19,928
  • 7
  • 68
  • 105
2

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
  • 11,229
  • 20
  • 79
  • 114
  • 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. – Tyler Mar 05 '10 at 21:01
0

You can use set operation to find Symmetric difference (^) between two lists. This is one of the best pythonic ways to do this.

list1=[1,2,3,4]
list2=[1,5,3,4]

print(set(list1) ^ set(list2))

So the output will be {2, 5}