如何检查列表是否已排序?

时间:2011-01-17 07:03:57

标签: python sorting

  

可能重复:
  Pythonic way to check if a list is sorted or not

在python中,如何测试数字列表是否已经排序?

5 个答案:

答案 0 :(得分:22)

这只能通过遍历列表(隐式或显式)来实现:

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)快10000多倍。

答案 1 :(得分:10)

some_list == sorted(some_list)

答案 2 :(得分:6)

通常,您应该已经知道列表是否已排序(因为这是您的输入的定义方式,或者您之前对其进行了排序)。

如果您需要验证列表是否已排序,因为如果不是,则要对其进行排序,只需对其进行排序即可。如果列表已经排序,这是一个便宜的操作,并不比明确验证订单贵很多。

换句话说:

mylist.sort()

现在你知道它的排序。

答案 3 :(得分:5)

对其他答案的评论多于答案,但此网站无法做出正确的评论。

如果列表已经部分或完全排序,排序解决方案会更快。如果列表可能是随机顺序,或者如果列表早期出现故障,则迭代解决方案会更快。

这有两个原因。首先,当Python以它理解的顺序(部分排序,反转等)给出数据时,Python的排序非常好,但如果数据是随机的或其他不可预测的,那么它不会比任何其他类型更好。其次,迭代解决方案可以在没有工作的情况下进行短路,如果它早期发现列表未被排序。

这显示了相反的极端:

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

因此,在这些极端情况下,排序方法的速度提高了大约三倍,线性方法的速度提高了约20万倍。

请注意,这里的真正区别是 O(n)与O(n log n);这些复杂性之间的差异并不是那么广泛。主要的区别在于线性版本一发现两个乱序值就会短路,排序版本总是需要完成所有工作。

本机实现可以获得两者的理想性能,提供O(n)复杂性,短路能力以及本机代码的低开销,这使得排序方法更快。如果(并且只有!)表现真的很重要,那将是正确的解决方案。

(请注意,通常我不建议选择基于性能的解决方案,除非性能实际上是一个问题,但是值得注意的是,因为这两种方法都不比另一种方法简单得多。排序版本有点简单易懂但是,迭代版本也没有什么复杂的。)

答案 4 :(得分:-3)

if 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"