以与另一个列表相同的顺序放置一个列表 [英] Putting a list in the same order as another list

查看:77
本文介绍了以与另一个列表相同的顺序放置一个列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一堆类似的措词,但是我找不到真正映射到我想要的语义的问题.

There's a bunch of questions that are phrased similarly, but I was unable to find one that actually mapped to my intended semantics.

有两个列表,AB,我想重新排列B,使它与A处于相同的相对顺序-B的最大元素在同一位置作为A的最大元素的当前位置,与最小元素的当前位置相同,依此类推.

There are two lists, A and B, and I want to rearrange B so that it is in the same relative order as A - the maximum element of B is in the same position as the current position of the maximum element of A, and the same for the minimum element, and so on.

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

Note that A is not sorted, nor do I want it to be.

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

As an example, if the following were input:

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

我希望输出为[0, 42, -1, 0, 45, 1].

请注意,预期的输出不是[0, 45, 1, 0, 42, -1],这就是您将两者压缩并按A排序并采用B的结果元素的结果(这是所有其他问题的含义)我看着被通缉.)

Please note that the intended output is not [0, 45, 1, 0, 42, -1], which is what it would be it you zipped the two and sorted by A and took the resulting elements of B (this is what all of the other questions I looked at wanted).

这是我的代码:

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))

该方法基本上是构造一个通过选择排序对A进行排序,对B进行排序所必需的交换列表,然后反向应用这些交换.这是可行的,但速度很慢(也相当令人困惑).有更好的方法吗?

The approach is basically to construct a list of the swaps necessary to sort A via selection sort, sort B, and then apply those swaps in reverse. This works, but is pretty slow (and is fairly confusing, as well). Is there a better approach to this?

推荐答案

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])

结果:

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

使用enumeratea进行排序,以跟踪每个项目的原始索引.用sorted(b)压缩结果,然后根据a的原始索引对整个内容重新排序.然后,再次调用zip以仅提取b的值.

You sort a, using enumerate to keep track of each item's original index. You zip the result with sorted(b), then re-sort the whole thing based on a's original indices. Then you call zip once more to extract just b's values.

这篇关于以与另一个列表相同的顺序放置一个列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆