I am trying to write a function that will test whether or not a list is in decending order. This is what I have so far, but it doesn\'t seem to be working for all lists. <
I originally proposed using sorted, and it was pointed out to me that it may be less efficient than your iteration.
>>> l = [3, 1, 2]
>>> l == sorted(l, reverse=True)
False
>>> l = [3, 2, 1]
>>> l == sorted(l, reverse=True)
True
So I benchmarked the accepted answer, mine, Lattyware's generator solution, and the same with itertools.izip. I intentionally used a case that I believed would favor my sorted
solution: a list that is only out-of-order at the end. These benchmarks were performed on Python 2.7.1 on an old OpenBSD machine.
sorted.py
import time
l = list(reversed(range(99998) + [99999, 99998]))
start = time.time()
for count in range(100):
l == sorted(l)
end = time.time()
print('elapsed: {}'.format(end - start))
walk.py
import time
def ordertest(l):
for i in range(len(l) - 1):
if l[i] < l[i+1]:
return False
return True
l = list(reversed(range(99998) + [99999, 99998]))
start = time.time()
for count in range(100):
ordertest(l)
end = time.time()
print('elapsed: {}'.format(end - start))
generator.py
import time
l = list(reversed(range(99998) + [99999, 99998]))
start = time.time()
for count in range(100):
all(earlier >= later for earlier, later in zip(l, l[1:]))
end = time.time()
print('elapsed: {}'.format(end - start))
izip.py
import itertools
import time
l = list(reversed(range(99998) + [99999, 99998]))
start = time.time()
for count in range(100):
all(earlier >= later for earlier, later in itertools.izip(l, l[1:]))
end = time.time()
print('elapsed: {}'.format(end - start))
The results:
$ python sorted.py
elapsed: 1.0896859169
$ python walk.py
elapsed: 0.641126155853
$ python generator.py
elapsed: 4.79061508179
$ python izip.py
elapsed: 0.363445997238
As pointed out in the comments to this answer, the generator expression is likely made slow by zip
making a copy of the list. Using izip
beats all.