在Python中,如何测试一个数字列表是否已经排序?
只有通过对列表进行迭代(隐式或显式)才能实现这一点:
all(b >= a for a, b in zip(the_list, the_list[1:])
如果你需要对列表进行排序,为什么不直接对其排序呢?在已经排序的列表上,Python的排序算法会非常便宜,可能比上面的测试还要便宜。
编辑:由于这变成了有关性能的讨论,因此这里提供了一种使用惰性迭代器的版本:
it = iter(the_list)
it.next()
all(b >= a for a, b in itertools.izip(the_list, it))
对于一个随机排序的含有一百万个元素的列表而言,这种方法比the_list == sorted(the_list)
要快超过一万倍。
some_list == sorted(some_list)
通常情况下,您应该已经知道列表是否已排序(因为这是您的输入定义方式,或者您之前已经对其进行了排序)。
如果您需要验证列表是否已排序,因为如果没有排序,您想要对其进行排序,请直接对其进行排序。如果列表已经排序,那么这是一项廉价操作,而且比显式验证顺序的成本稍微高一些。
换句话说:
mylist.sort()
现在你知道它已经排序了。
import timeit, random, itertools
def a(data):
return all(b >= a for a, b in itertools.izip(data, itertools.islice(data, 1, None)))
def b(data):
return data == sorted(data)
def main():
data = range(1000000)
print "Sorted, iterative:", timeit.timeit(lambda: a(data), number=10)
print "Sorted, sort:", timeit.timeit(lambda: b(data), number=10)
random.shuffle(data)
print "Random, iterative:", timeit.timeit(lambda: a(data), number=10)
print "Random, sort:", timeit.timeit(lambda: b(data), number=10)
Sorted, iterative: 1.42838597298
Sorted, sort: 0.498414993286
Random, iterative: 0.000043
Random, sort: 10.5548219681
for a, b in izip(data,islice(data, 1, None)):if a > b: return False
比 all()
变体快约50%。 - jfsif L == (lambda pp=[]: reduce(lambda p, i: pp.append(reduce(lambda t, i:
(lambda t, i, j: (lambda l=[]: map(lambda x: (lambda xx=l.append(1):
t[sum(l) - 1] if sum(l) not in map(1..__radd__, (i, j)) else (t[i] if
sum(l) == j + 1 else t[j]))(), t))())(t, i, i + 1) if t[i] >= t[i + 1]
else t, xrange(len(p) - 1), p)) or pp[-1], iter(lambda: len(pp) >= 2
and list.__eq__(*pp[-2:]), True), L))():
print "yeah, it's sorted"
some_list == sorted(some_list)
在任何情况下都是更好的解决方案。 - Lennart Regebroitertools.izip
,尤其是在测试早期短路的情况下,速度会更快。如果您的列表已经按可预测或预排序的顺序排列,则排序将更快,因为Python的排序在这方面很好,而此测试无法短路。当然,如果性能真的很重要(OP没有说过),那么本地模块可以获得两全其美的效果。 - Glenn Maynardzip()
期间;请注意,the_list[1:]
复制了列表)。为了完整起见,我将添加一个使用惰性迭代器的解决方案。 - Sven Marnachnext(it, None)
代替it.next()
以避免StopIteration异常(空列表是有效输入(始终排序))。微小的挑剔:a <= b
更容易阅读(一开始我认为您的代码检查降序是由于>=
)。 - jfs