В чем разница между "отсортированным(списком)" и "списком".сортировка ()`?
list.sort() сортирует список и сохраняет отсортированный список, в то время как sorted(list) возвращает отсортированную копию списка, не изменяя исходный список.
- но когда какую использовать?
- а что быстрее? И насколько быстрее?
- можно ли восстановить исходные позиции списка после
list.sort()?
4 ответа:
sorted()возвращает a новая отсортированный список, оставляя исходный список без изменений.list.sort()сортировка списка на месте, мутируя индексы списка, и возвращаетNone(как и все операции на месте).
sorted()работает на любой итерации, а не только списки. Строки, кортежи, словари (вы получаете ключи), генераторы и т. д., возвращая список, содержащий все элементы, отсортированы.
использовать
list.sort()когда вы хотите мутировать список,sorted()когда вы хотите новый отсортированный объект. Используйтеsorted()когда вы хотите отсортировать что-то, что является итерацией, а не списком пока.для списков,
list.sort()быстрееsorted()потому что он не должен создавать копию. Для любой другой итерации у вас нет выбора.нет, вы не можете получить исходные позиции. Как только вы позвонили
list.sort()первоначальный заказ исчез.
в чем разница между
sorted(list)vslist.sort()?
list.sortизменяет список на месте и возвращаетNonesortedпринимает любой iterable и возвращает новый список, отсортированный.
sortedэквивалентно этой реализации Python, но встроенная функция CPython должна работать значительно быстрее, поскольку она написана на C:def sorted(iterable, key=None): new_list = list(iterable) # make a new list new_list.sort(key=key) # sort it return new_list # return itкогда использовать какой?
- использовать
list.sortесли вы не хотите сохранять исходный порядок сортировки (Таким образом, Вы сможете использовать список в памяти.) и когда вы являетесь единственным владельцем списка (если список используется другой код и вы мутируете его, вы можете ввести ошибки, где этот список используется.)- использовать
sortedесли вы хотите сохранить исходный порядок сортировки или когда вы хотите создать новый список, только ваш код владеет.можно ли получить исходные позиции списка после списка.сортировка ()?
нет - если вы не сделали копию себе, эта информация будет потеряна, потому что сортировка выполняется на месте.
"а что быстрее? И насколько быстрее?"
чтобы проиллюстрировать штраф за создание нового списка, используйте модуль timeit, вот наша настройка:
import timeit setup = """ import random lists = [list(range(10000)) for _ in range(1000)] # list of lists for l in lists: random.shuffle(l) # shuffle each list shuffled_iter = iter(lists) # wrap as iterator so next() yields one at a time """и вот наши результаты для списка хаотично расположенные 10000 целых чисел, как мы видим здесь, мы опровергнуть старый миф о расходах на создание списка:
Python 2.7
>>> timeit.repeat("next(shuffled_iter).sort()", setup=setup, number = 1000) [3.75168503401801, 3.7473005310166627, 3.753129180986434] >>> timeit.repeat("sorted(next(shuffled_iter))", setup=setup, number = 1000) [3.702025591977872, 3.709248117986135, 3.71071034099441]Python 3
>>> timeit.repeat("next(shuffled_iter).sort()", setup=setup, number = 1000) [2.797430992126465, 2.796825885772705, 2.7744789123535156] >>> timeit.repeat("sorted(next(shuffled_iter))", setup=setup, number = 1000) [2.675589084625244, 2.8019039630889893, 2.849375009536743]
после некоторой обратной связи я решил, что еще один тест будет желательным с разными характеристиками. Здесь я предоставляю один и тот же случайно упорядоченный список длиной 100 000 для каждой итерации 1000 раз.
import timeit setup = """ import random random.seed(0) lst = list(range(100000)) random.shuffle(lst) """я интерпретирую разницу этого большего рода исходя из копирования, упомянутого Martijn, но он не доминирует до точки, указанной в более старом более популярном ответе здесь, здесь увеличение времени составляет всего около 10%
>>> timeit.repeat("lst[:].sort()", setup=setup, number = 10000) [572.919036605, 573.1384446719999, 568.5923951] >>> timeit.repeat("sorted(lst[:])", setup=setup, number = 10000) [647.0584738299999, 653.4040515829997, 657.9457361929999]я также пробежал выше по гораздо меньшему виду, и увидел, что новый
sortedкопирование версии по-прежнему занимает около 2% больше времени работы на своего рода 1000 длины.Poke также запустил свой собственный код, вот код:
setup = ''' import random random.seed(12122353453462456) lst = list(range({length})) random.shuffle(lst) lists = [lst[:] for _ in range({repeats})] it = iter(lists) ''' t1 = 'l = next(it); l.sort()' t2 = 'l = next(it); sorted(l)' length = 10 ** 7 repeats = 10 ** 2 print(length, repeats) for t in t1, t2: print(t) print(timeit(t, setup=setup.format(length=length, repeats=repeats), number=repeats))он нашел для 1000000 сортировка длины, (ran 100 times) аналогичный результат, но только около 5% увеличения времени, вот результат:
10000000 100 l = next(it); l.sort() 610.5015971539542 l = next(it); sorted(l) 646.7786222379655вывод:
большой размер списка сортируется с
sortedсоздание копии, скорее всего, будет доминировать над различиями, но сама сортировка доминирует над операцией, и организация вашего кода вокруг этих различий будет преждевременной оптимизацией. Я бы использовалsortedкогда мне нужен новый отсортированный список данных, и я хотел бы использоватьlist.sortкогда мне нужно отсортировать список на месте, и пусть это определяет мое использование.
главное отличие в том, что
sorted(some_list)возвращает a новаяlist:a = [3, 2, 1] print sorted(a) # new list print a # is not modifiedи
some_list.sort(),сортировка списка на месте:a = [3, 2, 1] print a.sort() # in place print a # it's modifiedПримечание вот так
a.sort()ничего не возвращает,print a.sort()печатиNone.
можно ли получить исходные позиции списка после списка.сортировка ()?
нет, потому что он изменяет исходный список.
The .функция sort () сохраняет значение нового списка непосредственно в переменной list; поэтому ответ на ваш третий вопрос будет нет. Кроме того, если вы делаете это с помощью sorted(list), то вы можете получить его использовать, потому что он не хранится в переменной list. Тоже иногда .метод sort () действует как функция, или говорят, что он принимает аргументы в нем.
вы должны хранить значение сортируется(список) в переменной явно.
также для обработки данных о скорости нет разница; но для длинных списков; вы должны непосредственно использовать .sort () метод для быстрой работы; но снова вы столкнетесь с необратимыми действиями.