Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Python keep track of when something has been sorted, internally?

For example, if I call

L = [3,4,2,1,5]
L = sorted(L)

I get a sorted list. Now, in the future, if I want to perform some other kind of sort on L, does Python automatically know "this list has been sorted before and not modified since, so we can perform some internal optimizations on how we perform this other kind of sort" such as a reverse-sort, etc?

like image 849
AureliusPhi Avatar asked Oct 30 '14 14:10

AureliusPhi


3 Answers

Nope, it doesn't. The sorting algorithm is designed to exploit (partially) sorted inputs, but the list itself doesn't "remember" being sorted in any way.

(This is actually a CPython implementation detail, and future versions/different implementations could cache the fact that a list was just sorted. However, I'm not convinced that could be done without slowing down all operations that modify the list, such as append.)

like image 180
Fred Foo Avatar answered Oct 08 '22 09:10

Fred Foo


As the commenters pointed out, normal Python lists are inherently ordered and efficiently sortable (thanks, Timsort!), but do not remember or maintain sorting status.

If you want lists that invariably retain their sorted status, you can install the SortedContainers package from PyPI.

>>> from sortedcontainers import SortedList
>>> L = SortedList([3,4,2,1,5])
>>> L
SortedList([1, 2, 3, 4, 5])
>>> L.add(3.3)
>>> L
SortedList([1, 2, 3, 3.3, 4, 5])

Note the normal append method becomes add, because the item isn't added on the end. It's added wherever appropriate given the sort order. There is also a SortedListWithKey type that allows you to set your sort key/order explicitly.

like image 32
Jonathan Eunice Avatar answered Oct 08 '22 07:10

Jonathan Eunice


Some of this, at least the specific reverse sort question, could be done using numpy:

import numpy as np
L = np.array([3,4,2,1,5])
a = np.argsort(L)
b = L[a]
r = L[a[::-1]]

print L
[3 4 2 1 5]

print b
[1 2 3 4 5]

print r
[5, 4, 3, 2, 1]

That is, here we just do the sort once (to create a, the sorting indices), and then we can manipulate a, to do other various sorts, like the normal sort b, and the reverse sort r. And many others would be similarly easy, like every other element.

like image 1
tom10 Avatar answered Oct 08 '22 09:10

tom10