Esta es una vieja pregunta, pero algunas de las respuestas que veo publicadas en realidad no funcionan porque zip
no son programables. Otras respuestas no molestaron aimport operator
y proporcionaron más información sobre este módulo y sus beneficios aquí.
Hay al menos dos buenas expresiones idiomáticas para este problema. Comenzando con el ejemplo de entrada que proporcionó:
X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1 ]
Esto también se conoce como la transformación Schwartzian después de R. Schwartz, que popularizó este patrón en Perl en los años 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')
Tenga en cuenta que en este caso Y
y X
se ordenan y comparan lexicográficamente. Es decir, Y
se comparan los primeros elementos (de ); y si son iguales, X
se comparan los segundos elementos (de ), y así sucesivamente. Esto puede crear inestabilidad salidas menos que incluya los índices de la lista original para el orden lexicográfico para mantener los duplicados en su orden original.
Esto le brinda un control más directo sobre cómo ordenar la entrada, para que pueda obtener estabilidad de la clasificación simplemente indicando la clave específica para clasificar. Ver más ejemplos aquí .
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')