Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing Order of 2 Python Lists

I am looking for some help comparing the order of 2 Python lists, list1 and list2, to detect when list2 is out of order.

  • list1 is static and contains the strings a,b,c,d,e,f,g,h,i,j. This is the "correct" order.
  • list2 contains the same strings, but the order and the number of strings may change. (e.g. a,b,f,d,e,g,c,h,i,j or a,b,c,d,e)

I am looking for an efficient way to detect when list2 is our of order by comparing it against list1.

For example, if list2 is a,c,d,e,g,i should return true (as the strings are in order)

While, if list2 is a,d,b,c,e should return false (as string d appears out of order)

like image 217
chasm Avatar asked Dec 14 '22 06:12

chasm


1 Answers

First, let's define list1:

>>> list1='a,b,c,d,e,f,g,h,i,j'.split(',')
>>> list1
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']

While your list1 happens to be in alphabetical order, we will not assume that. This code works regardless.

Now, let's create a list2 that is out-of-order:

>>> list2 = 'a,b,f,d,e,g,c,h,i,j'.split(',')
>>> list2
['a', 'b', 'f', 'd', 'e', 'g', 'c', 'h', 'i', 'j']

Here is how to test whether list2 is out of order or not:

>>> list2 == sorted(list2, key=lambda c: list1.index(c))
False

False means out-of-order.

Here is an example that is in order:

>>> list2 = 'a,b,d,e'.split(',')
>>> list2 == sorted(list2, key=lambda c: list1.index(c))
True

True means in-order.

Ignoring elements of list1 not in list2

Let's consider a list2 that has an element not in list1:

>>> list2 = 'a,b,d,d,e,z'.split(',')

To ignore the unwanted element, let's create list2b:

>>> list2b = [c for c in list2 if c in list1]

We can then test as before:

>>> list2b == sorted(list2b, key=lambda c: list1.index(c))
True

Alternative not using sorted

>>> list2b = ['a', 'b', 'd', 'd', 'e']
>>> indices = [list1.index(c) for c in list2b]
>>> all(c <= indices[i+1] for i, c in enumerate(indices[:-1]))
True
like image 78
John1024 Avatar answered Dec 16 '22 18:12

John1024