views:

243

answers:

4

Let's say we have a list:

a = [4, 8, 1, 7, 3, 0, 5, 2, 6, 9]

Now, a.sort() will sort the list in place. What if we want to sort only a part of the list, still in place? In C++ we could write:

int array = { 4, 8, 1, 7, 3, 0, 5, 2, 6, 9 };
int * ptr = array;
std::sort( ptr + 1, ptr + 4 );

Is there a similar way in Python?

A: 

A more pythonic solution might be:

# i,j = range to sort.
a = a[:i] + sorted(a[i:j]) + a[j:]

This is not sorted 'in place', but that seems like an artificial requirement. Happy to hear why that could be a requirement, though. ;)

Matthew Schinckel
a[i:j] = sorted(a[i:j]) seems better
SurDin
Well, wouldn't that artificial requirement make some sense if, let's say, the list is really freaking huge?
Headcrab
@SurDin: Post that as a separate answer, please.
S.Lott
A: 

Based on your requirements, I'd suggest creating your own sort function/ a wrapper class for the list with a sort function which staisfies your requirement.

You might consider the DSU idiom or the schwartzian transform: See http://wiki.python.org/moin/HowTo/Sorting and http://wiki.python.org/moin/PythonSpeed/PerformanceTips. I suggest you decorate with 0 up until i, the element between i and j and 0 again j onwards. Then, use a custom comparison function to return 0 if either x or y is zero get the sort to work! This may not help, since we crossed Python V2.4 long ago. Still, this might be what you are looking for.

This answer fills in while I try figure out if it can be done with less effort!

batbrat
+14  A: 

I'd write it this way:

a[i:j] = sorted(a[i:j])

It is not in-place sort either, but fast enough for relatively small segments.

Please note, that Python copies only object references, so the speed penalty won't be that huge compared to a real in-place sort as one would expect.

fviktor
+2  A: 

if a is a numpy array then to sort [i, j) range in-place, type:

a[i:j].sort()

Example:

>>> import numpy as np
>>> a = np.array([4, 8, 1, 7, 3, 0, 5, 2, 6, 9])
>>> a[1:4].sort()
>>> a
array([4, 1, 7, 8, 3, 0, 5, 2, 6, 9])
J.F. Sebastian