Listing in the same order as another list

There are a bunch of questions that are worded in a similar way, but I could not find one that really matches my intended semantics.

There are two lists: Aand B, and I want to reorder Bso that it is in the same relative order as A- the maximum element Bis in the same position as the current position of the maximum element A, and the same for the minimum element, etc.

Please note that it is Anot sorted, and I do not want it to be.

As an example, if the following data has been entered:

a = [7, 14, 0, 9, 19, 9]
b = [45, 42, 0, 1, -1, 0]

I want the result to be [0, 42, -1, 0, 45, 1].

Note that the intended conclusion is not [0, 45, 1, 0, 42, -1], and that would be that you would pin two and sort by Aand take the resulting elements B(that’s what all the other questions I looked at wanted).

Here is my code:

def get_swaps(x):
    out = []

    if len(x) <= 1:
        return out

    y = x[:]
    n = -1

    while len(y) != 1:
        pos = y.index(max(y))
        y[pos] = y[-1]
        y.pop()
        out.append((pos, n))
        n -= 1

    return out

def apply_swaps_in_reverse(x, swaps):
    out = x[:]
    for swap in swaps[::-1]:
        orig, new = swap
        out[orig], out[new] = out[new], out[orig]
    return out

def reorder(a, b):
    return apply_swaps_in_reverse(sorted(b), get_swaps(a))

The approach basically consists in building the list of swaps needed for sorting Aby sorting sorting, sorting B, and then applying these swaps in reverse order. This works, but rather slowly (and rather confusingly). Is there a better approach to this?

+4
source share
2 answers
a = [7, 14, 0, 9, 19, 9]
b = [45, 42, 0, 1, -1, 0]
print zip(*sorted(zip(sorted(b), sorted(enumerate(a), key=lambda x:x[1])), key=lambda x: x[1][0]))[0]
#or, for 3.x:
print(list(zip(*sorted(zip(sorted(b), sorted(enumerate(a), key=lambda x:x[1])), key=lambda x: x[1][0])))[0])

result:

(0, 42, -1, 0, 45, 1)

a, enumerate . sorted(b), , a. zip , b.

+5

numpy, ( ) :

import numpy as np

a = [7, 14, 0, 9, 19, 9]
b = [45, 42, 0, 1, -1, 0]

a = np.array(a)
b = np.array(b)

ai = np.argsort(a)
bi = np.argsort(b)
aiinv = np.empty(ai.shape,dtype=int)
aiinv[ai] = np.arange(a.size)  # inverse of ai permutation

b_new = b[bi[aiinv]]
# array([ 0, 42, -1,  0, 45,  1])

numpy.argsort (), . b,

aiinv[ai] = np.arange(a.size)
+3

Source: https://habr.com/ru/post/1656134/


All Articles