В чем разница между "отсортированным(списком)" и "списком".сортировка ()`?
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
изменяет список на месте и возвращаетNone
sorted
принимает любой 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 () метод для быстрой работы; но снова вы столкнетесь с необратимыми действиями.