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,然后反向应用这些交换所需的交换列表.这有效,但速度很慢(而且相当混乱).有更好的方法吗?
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的价值观.