royskatt
royskatt

Reputation: 1210

Python - diff-like order comparision of 2 lists with unequal sizes,

I want to compare two lists and check, if the elements are in the same order:

a = [e, f, g, h, i]
b = [e, f, h, i, j, g]

I know the following approach, but that works only for lists of the same size:

[i for i, j in zip(a, b) if i == j]

How can I show diff-like the differences between two lists? As I said, I'm not talking about intersection (only) since the order matters as well.

I try to archive an output like:

a, b
e, e OK
f, f OK
g, h NOK
h, i NOK
i, j NOK
null, g NOK

Is there maybe any built-in function, at least for diffing 2 sets in the way described?

Upvotes: 0

Views: 113

Answers (3)

Padraic Cunningham
Padraic Cunningham

Reputation: 180481

You could use enumerate and add on the elements from the longer list.

a = ["e", "f", "g", "h", "i"]
b = ["e", "f", "h", "i", "j", "g"]

m_len = len(min(a, b))
mx = max(a, b)
d = [[a[i], b[i], "Ok"] if a[i] == b[i] else [ a[i], b[i],"NOK"] for i, j in enumerate(min(a, b))]
d += [["null", x, "NOK"] for x in mx[m_len:]]
print "a" ," b"
for i,j,k in d:
    print('{}, {} {}'.format(i, j, k))


a  b
e, e Ok
f, f Ok
g, h NOK
h, i NOK
i, j NOK
null, g NOK

Upvotes: 1

dano
dano

Reputation: 94931

I'm adding a second answer for this, because it's a very different approach...

You can use difflib for this, if you want truly diff-like functionality. For example:

>>> for x in difflib.unified_diff(a, b, lineterm=""): print(x)
... 
--- 
+++ 
@@ -1,5 +1,6 @@
 e
 f
-g
 h
 i
+j
+g

>>> for x in difflib.ndiff(a, b): print(x)
... 
  e
  f
- g
  h
  i
+ j
+ g

I'm not sure if this is really what you want, given the example output you provided, but just letting you know it exists.

Upvotes: 1

dano
dano

Reputation: 94931

You can use itertools.izip_longest for this (note that this is renamed zip_longest in Python 3.x):

 [i for i, j in izip_longest(a, b) if i == j]

Once the shorter itertable is exhausted, izip_longest will use whatever is entered as the fillvalue keyword argument (in this, None, since we didn't provide the parameter).

Edit:

If you want output that matches what you have in your original question, you can do this:

>>> print("\n".join(["{}, {} {}OK".format(i, j, "" if i == j else "N") for i, j in izip_longest(a, b, fillvalue="null")]))
e, e OK
f, f OK
g, h NOK
h, i NOK
i, j NOK
null, g NOK

Upvotes: 2

Related Questions