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