sort array, apply rearrangement to second

Steve Howell showell30 at yahoo.com
Thu Apr 1 10:59:41 EDT 2010


On Mar 31, 1:09 pm, Raymond Hettinger <pyt... at rcn.com> wrote:
> On Mar 30, 4:25 pm, s... at sig.for.address (Victor Eijkhout) wrote:
>
> > I have two arrays, made with numpy. The first one has values that I want
> > to use as sorting keys; the second one needs to be sorted by those keys.
> > Obviously I could turn them into a dictionary  of pairs and sort by the
> > first member, but I think that's not very efficient, at least in space,
> > and this needs to be done as efficiently as possible.
>
> Alf's recommendation is clean and correct.  Just make a list of
> tuples.
>
> FWIW, here's a little hack that does the work for you:
>
> >>> values = ['A', 'B', 'C', 'D', 'E']
> >>> keys = [50, 20, 40, 10, 30]
> >>> keyiter = iter(keys)
> >>> sorted(values, key=lambda k: next(keyiter))
>
> ['D', 'B', 'E', 'C', 'A']
>

Another option:

[values[i] for i in sorted(range(len(keys)), key=lambda i: keys[i])]

Sort the indexes according to keys values, then use indexes to get the
values.

It might read more clearly when broken out into two lines:

>>> sorted_indexes = sorted(range(len(keys)), key = lambda i: keys[i])
>>> sorted_indexes
[3, 1, 4, 2, 0]
>>> [values[i] for i in sorted_indexes]
['D', 'B', 'E', 'C', 'A']

The advantage of Raymond's solution is that he only creates one new
Python list, whereas my solutions create an intermediate Python list
of integers.  I don't think my solution really is that space-wasteful,
though, since by the time the second list gets created, any internal
intermediate lists from CPython's sorted() implementation will
probably have been cleaned up.






More information about the Python-list mailing list