2011-01-17 5 views

ответ

10
some_list == sorted(some_list) 
+7

Это необязательно «O (n log n)» и не короткое замыкание. –

+1

Прошу прощения, но это не может быть лучшим ответом. Зачем вам заказывать все, чтобы сравнить весь набор, когда вы можете опровергнуть раннее, что что-то не заказано? –

22

Это возможно только итерацию по списку (явно или неявно):

all(b >= a for a, b in zip(the_list, the_list[1:]) 

Но почему бы не просто разбирайтесь, если вам это нужно, чтобы быть отсортирован? Алгоритм сортировки Python будет действительно дешевым в уже отсортированном списке - возможно, дешевле, чем выше.

EDIT: Потому что это превратилось в дискуссию о производительности, вот версия с использованием ленивых итераторов:

it = iter(the_list) 
it.next() 
all(b >= a for a, b in itertools.izip(the_list, it)) 

Для случайного образом упорядоченного списка с миллионами записей, это более чем в 10000 раз быстрее, чем the_list == sorted(the_list).

+0

Действительно, этот тест занимает примерно в два раза больше, чем его сортировка. Но тестирование для равенства после сортировки занимает почти нет времени в сравнении, поэтому 'some_list == sorted (some_list)' является лучшим решением в любом случае. –

+1

Это значительно быстрее, чем сортировка для произвольно упорядоченных списков. Это даже быстрее, если вы используете 'itertools.izip' вместо этого, особенно если тест коротких замыканий рано. Сортировка будет быстрее, если ваши списки уже находятся в предсказуемом или предварительно отсортированном порядке, так как сортировка Python хороша, и этот тест не может быть короткозамкнутым. Если производительность действительно имеет значение (OP не сказал, что это так), то, естественно, собственный модуль мог бы получить лучшее из обоих миров. –

+0

@Glenn, @Lennart: Это явно не было написано с представлением в больших списках. Дополнительная память, которую он использует, по крайней мере в три раза превышает память, которую использует исходный список (во время выполнения 'zip()'; обратите внимание, что 'the_list [1:]' копирует список). Я добавлю решение, используя ленивые итераторы для полноты. –

6

Как правило, вы уже должны знать, отсортирован ли список (потому что именно так определяется ваш ввод или вы его отсортировали ранее).

Если вам нужно проверить, отсортирован ли список, потому что, если это не так, вы хотите его отсортировать, просто выполните сортировку. Это дешевая операция, если список уже отсортирован, и не намного дороже, чем проверка заказа явно.

Другими словами:

mylist.sort() 

теперь вы знаете это сортируется.

+0

С помощью некоторых алгоритмов сортировки сортировка уже отсортированного списка является дорогостоящей операцией. Это не с Timsort, но, очевидно, это деталь реализации Python. –

+0

Также полезно знать, отсортирован ли список или нет для определенных проблемных областей - вы не обязательно хотите, чтобы элементы сортировались BE, вы просто хотите знать, являются ли они. Очевидным случаем является запись единичного теста для функции сортировки. :) – fluffy

-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" 
+3

what !? как это полезно? Это не односторонний конкурс. Бросьте несколько новых линий там, и некоторые комментарии, и у вас будет код, остальной мир не прочь прочесть. – sbartell

+2

@ J.F. Себастьян, в случае, если это было неясно, мой код делает вид пузыря в рассматриваемом списке, а затем проверяет, соответствует ли результат исходному списку. – habnabit

+2

Урон от мозга, который пытается понять, как это работает, гарантируется. Неожиданное путешествие с отладчиком еще более увлекательно! И я хочу посмотреть на лицо другого разработчика в группе, открыв код в их прекрасной IDE, а потом увидев это :))). Я думаю, они пойдут после автора такого кода с битой :) – DmitrySemenov

5

Еще комментарий к другим ответам, чем ответ, но этот сайт делает правильные комментарии невозможными.

Решения сортировки выполняются быстрее, если список уже частично или полностью отсортирован. Итеративные решения быстрее, если список, вероятно, будет в случайном порядке или если список не работает раньше.

Это по двум причинам. Во-первых, сорт 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 

Таким образом, в этих экстремальных сортировочный подход примерно в три раза быстрее, а линейный подход есть примерно ... двести тысяч раз быстрее.

Обратите внимание, что реальная разница здесь не O (n) против O (n log n); различие между этими сложностями не так велико. Основное отличие состоит в том, что линейная версия может быть короткой, как только обнаружится два значения, которые не соответствуют порядку, где версия сортировки всегда должна выполнять всю работу.

Натуральная реализация может обеспечить идеальную производительность обоих, обеспечивая сложность O (n), способность к короткому замыканию и низкую накладную часть собственного кода, что ускоряет сортировку. Если (и только если!) Производительность действительно имеет значение, это было бы правильным решением.

(Обратите внимание, что обычно я бы не рекомендовал выбирать решение на основе производительности, если только производительность не была проблемой, но стоит отметить это, поскольку ни один из подходов не намного проще, чем другой. Сортировочная версия немного проще понимайте, но нет ничего сложного и в итеративной версии.)

+0

+1 для последнего абзаца. Если производительность имеет значение, то явный цикл 'для a, b в izip (data, islice (data, 1, None)): если a> b: return False' ~ на 50% быстрее, чем вариант« all() ». – jfs