将列表放在与另一个列表相同的顺序中

Kev*_*vin 4 python sorting list

有很多类似的措辞,但我无法找到一个实际映射到我的预期语义的问题.

有两个列表,A并且B,我想重新排列B,使它与相同的相对顺序A- 最大元素位于与最大元素B的当前位置相同的位置A,并且对于最小元素是相同的,等等.

请注意,A没有排序,我也不希望它.

例如,如果输入以下内容:

a = [7, 14, 0, 9, 19, 9]
b = [45, 42, 0, 1, -1, 0]
Run Code Online (Sandbox Code Playgroud)

我想要输出[0, 42, -1, 0, 45, 1].

请注意,预期的输出不是[0, 45, 1, 0, 42, -1],这就是你将它们压缩并排序A并获取所得到的元素B(这是我所看到的所有其他问题所需要的).

这是我的代码:

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))
Run Code Online (Sandbox Code Playgroud)

该方法基本上是构建一个A通过选择排序,排序B,然后反向应用这些交换所需的交换列表.这有效,但速度很慢(而且相当混乱).有更好的方法吗?

Kev*_*vin 5

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])
Run Code Online (Sandbox Code Playgroud)

结果:

(0, 42, -1, 0, 45, 1)
Run Code Online (Sandbox Code Playgroud)

您可以排序a,enumerate用于跟踪每个项目的原始索引.您将结果压缩sorted(b),然后根据a原始索引重新排序整个事物.然后你zip再次打电话来提取你b的价值观.