使用由两个列表排序产生的排序对第三个列表进行排序?

Ped*_*dsB 2 python sorting list

假设我有三个列表:

X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
Y = [ 0,   1,   1,    0,   1,   2,   2,   0,   1]
Z = [ 5,   2,   3,    1,   4,   9,   6,   0,   7]
Run Code Online (Sandbox Code Playgroud)

我可以很容易地根据 Y 对 X 进行排序:

XY_sort = [x for _,x in sorted(zip(Y,X))]
print(XY_sort)  # ["a", "d", "h", "b", "c", "e", "i", "f", "g"]
Run Code Online (Sandbox Code Playgroud)

当我想根据产生 XY_sort 的排序对列表 Z 进行排序时,就会出现疑问。理想情况下,我想结束:

Z_sort = [5,   1,   0,   2,   3,   4,   7,   9,   6]
Run Code Online (Sandbox Code Playgroud)

我猜最好的方法是在 X 被排序到 XY_sort 时以某种方式存储它的排序索引,然后使用它们对 Z 进行排序,但我不知道我将如何去做。任何帮助将不胜感激!

Mar*_*yer 6

你可以用同样的方式排序。它将首先按 Y 排序,然后按 X,如果两者相同,则按 Z 排序:

X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
Y = [ 0,   1,   1,    0,   1,   2,   2,   0,   1]
Z = [ 5,   2,   3,    1,   4,   9,   6,   0,   7]


XYZ_sort = [z for y,x,z in sorted(zip(Y,X,Z))]
# [5, 1, 0, 2, 3, 4, 7, 9, 6]
Run Code Online (Sandbox Code Playgroud)

[感谢评论者的坚韧编辑]
如果X-Y组合可能不是唯一的,并且在这些情况下保留 Z 的相对顺序很重要,则可以将其operator.itemgetter()作为键传递给排序以获得干净的解决方案:

from operator import itemgetter

X = ["a", "b", "c", "a", "d", "e", "f", "g", "h", "i", "a"]
Y = [ 0,   1,   1,   0,  0,   1,   2,   2,   0,   1,  0]
Z = [ 5,   2,   3,  -1,  1,   4,   9,   6,   0,   7,  1]

XYZ_sort = [z for y,x,z in sorted(zip(Y,X,Z), key=itemgetter(0, 1))]

#preseves the relative order of 5, -1, and 1
# [5, -1, 1, 1, 0, 2, 3, 4, 7, 9, 6]
Run Code Online (Sandbox Code Playgroud)