views:

418

answers:

5

Is there a pythonic way to check if a list is already sorted in AESC or DESC.

listtimestamps=[1,2,3,5,6,7]

something like listtimestamps.isSorted() that returns True or False.

EDIT: I want to input a list of timestamps for some messages and check if the the transactions appeared in the correct order.

and I can write a custom function too :) , Thanks

EDIT: Thanks for pointing out camel case issues :)

EDIT: Also I am sorry if I wasn't clear I don't need to sort it afterwards, I just need to check if the list is sorted, I am using it to solve a decision problem

+7  A: 

I would just use

if sorted(lst) == lst:
    # code here

unless it's a very big list in which case you might want to create a custom function.

if you are just going to sort it if it's not sorted, then forget the check and sort it.

lst.sort()

and don't think about it too much.

if you want a custom function, you can do something like

def is_sorted(lst, key=lambda x, y: x < y):
    for i, el in enumerate(lst[1:]):
        if key(el, lst[i-1]):
            return False
    return True

This will be O(n) if the list is already sorted though (and O(n) in a for loop at that!) so, unless you expect it to be not sorted (and fairly random) most of the time, I would, again, just sort the list.

aaronasterling
If that's what you're going to do, you might as well just say: lst.sort() without the conditional check ;-)
SapphireSun
thats nlogn right there is a clearly faster way in O(n) using a simple for loop.
anijhaw
@SapphireSun. That's what I said ;)
aaronasterling
@anijhaw, See the update I made while you were leaving the comment. checking is O(n) and sorting is O(nlgn). is it better to incur an O(n) cost to just turn around and add O(nlgn) or just take the cost of sorting a sorted list wich is (i believe) O(n) for timsort.
aaronasterling
@ Aaron:Check the Edit to the original question,
anijhaw
+3  A: 

SapphireSun is quite right. You can just use lst.sort(). Python's sort implementation (TimSort) check if the list is already sorted. If so sort() will completed in linear time. Sounds like a Pythonic way to ensure a list is sorted ;)

Wai Yip Tung
Only linear time if the list is, in fact, sorted. If not, there is no short-circuit to skip the actual sorting task, so could be a huge penalty to pay if the list is long.
Paul McGuire
+17  A: 

Actually we are not giving the answer anijhaw is looking for. Here is the one liner:

all(l[i] <= l[i+1] for i in xrange(len(l)-1))
Wai Yip Tung
that's nice. You might want to wrap it in a function so your can pass a `key` function to use. `key=lambda x, y: x < y` makes a good default.
aaronasterling
@Wai Yip Tung: I guess you mean `l[i] <= l[i+1]`, right?
EOL
yes yes, thanks for the helpful comments.
Wai Yip Tung
+9  A: 

This iterator form is 10-15% faster than using integer indexing:

from itertools import izip
isSorted = lambda l : all(a <= b for a,b in izip(l[:-1],l[1:]))
Paul McGuire
+1  A: 

Here's an other way with eval and chained comparison from python :

a=[3,4,5,1]
isSorted = eval("<".join([str(v) for v in a]))

EDIT : Limitations :

This way is actually more a funny way to use chained comparison because there's a lot of problems :

  • For a=[x] it returns x
  • For big arrays, it raises a SystemError (com_backpatch: offset too large) (cf. here)
Elenaher
Should be "<=" instead of "<". How well does this work if `a = range(int(1e7))`?
Paul McGuire
@Paul McGuire : answer edited with limitations
Elenaher
You could do `len(a)<=1 or eval(etc...)` to explicitly handle the degenerate 0- and 1-length cases.
Paul McGuire