Esta é uma pergunta antiga, mas algumas das respostas que vejo postadas não funcionam de fato porque zip
não são programáveis. Outras respostas não se deram ao trabalho de import operator
fornecer mais informações sobre este módulo e seus benefícios aqui.
Existem pelo menos duas boas expressões para esse problema. Começando com a entrada de exemplo que você forneceu:
X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1 ]
Isso também é conhecido como Schwartzian_transform após R. Schwartz, que popularizou esse padrão em Perl nos anos 90:
# Zip (decorate), sort and unzip (undecorate).
# Converting to list to script the output and extract X
list(zip(*(sorted(zip(Y,X)))))[1]
# Results in: ('a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g')
Note-se que, neste caso, Y
e X
são ordenados e comparados lexicographically. Ou seja, os primeiros itens (de Y
) são comparados; e se forem iguais, os segundos itens (de X
) serão comparados e assim por diante. Isso pode criar instabilidade resultados menos que você inclua os índices da lista original da ordem lexicográfica para manter as duplicatas na ordem original.
Isso fornece um controle mais direto sobre como classificar a entrada, para que você possa obter estabilidade na classificação simplesmente indicando a chave específica a ser classificada. Veja mais exemplos aqui .
import operator
# Sort by Y (1) and extract X [0]
list(zip(*sorted(zip(X,Y), key=operator.itemgetter(1))))[0]
# Results in: ('a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g')