Tengo una lista de cadenas como esta:
X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
Y = [ 0, 1, 1, 0, 1, 2, 2, 0, 1 ]
¿Cuál es la forma más corta de ordenar X usando valores de Y para obtener el siguiente resultado?
["a", "d", "h", "b", "c", "e", "i", "f", "g"]
El orden de los elementos que tienen la misma "clave" no importa. Puedo recurrir al uso de for
construcciones, pero tengo curiosidad por saber si hay un camino más corto. ¿Alguna sugerencia?
Respuestas:
Código más corto
Ejemplo:
Generalmente hablando
Explicado:
zip
los doslist
s.list
función delzip
usosorted()
.list
.Para obtener más información sobre cómo configurar \ utilizar el
key
parámetro, así como lasorted
función en general, echar un vistazo a esto .fuente
Comprime las dos listas, clasifícalas y luego toma las partes que quieras:
Combina estos para obtener:
fuente
X
es una lista destr
, pero tenga cuidado si hay una posibilidad que<
no está definida para algunos pares de elementos enX
, por ejemplo, si algunos de ellos lo fueranNone
AttributeError: 'zip' object has no attribute 'sort'
es lo que obtengo a partir de ahora.sorted(zip(...))
todavía debería funcionar, o:them = list(zip(...)); them.sort()
Además, si no le importa usar matrices numpy (o de hecho ya está tratando con matrices numpy ...), aquí hay otra buena solución:
Lo encontré aquí: http://scienceoss.com/sort-one-list-by-another-list/
fuente
sortedArray1= array1[array2.argsort()]
. Y esto también facilita la clasificación de varias listas por una columna particular de una matriz 2D: por ejemplo,sortedArray1= array1[array2[:,2].argsort()]
ordenar la matriz1 (que puede tener varias columnas) por los valores en la tercera columna de la matriz2.La solución más obvia para mí es usar la
key
palabra clave arg.Tenga en cuenta que puede acortar esto a una frase si le interesa:
fuente
De hecho, vine aquí para ordenar una lista por una lista donde los valores coincidían.
fuente
index
realizará una búsqueda de O (N) quelist_a
resulte en unaO(N² log N)
ordenación.more_itertools
tiene una herramienta para ordenar iterables en paralelo:Dado
Manifestación
fuente
Me gusta tener una lista de índices ordenados. De esa manera, puedo ordenar cualquier lista en el mismo orden que la lista de origen. Una vez que tenga una lista de índices ordenados, una simple comprensión de la lista hará el truco:
Tenga en cuenta que la lista de índice ordenada también se puede obtener usando
numpy.argsort()
.fuente
Otra alternativa, combinando varias de las respuestas.
Para trabajar con python3:
fuente
zip, ordenar por la segunda columna, devolver la primera columna.
fuente
list(zip(*sorted(zip(X,Y), key=operator.itemgetter(1))))[0]
Una línea rápida.
Digamos que desea que la lista a coincida con la lista b.
Esto es útil cuando necesita ordenar una lista más pequeña a valores más grandes. Suponiendo que la lista más grande contiene todos los valores en la lista más pequeña, se puede hacer.
fuente
X
yY
?index
realizará una búsqueda de O (N) quelist_b
resulte en unaO(N² log N)
ordenación.Puede crear un
pandas Series
, utilizando la lista primaria comodata
y la otra lista comoindex
, y luego ordenar por el índice:salida:
fuente
Aquí está la respuesta de Whatangs si desea obtener ambas listas ordenadas (python3).
Solo recuerda que Zx y Zy son tuplas. También estoy deambulando si hay una mejor manera de hacerlo.
Advertencia: si lo ejecuta con listas vacías, se bloquea.
fuente
He creado una función más general, que clasifica más de dos listas basadas en otra, inspirada en la respuesta de @ Whatang.
fuente
Para obtener valores únicos presentes en
list2
Para encontrar la ubicación del índice en
list2
La ubicación del índice en
list2
se rastrea usandocur_loclist
[0, 3, 7, 1, 2, 4, 8, 5, 6]
fuente
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ó:
Usando el " Decorar-Ordenar-Decorar modismo "
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:
Tenga en cuenta que en este caso
Y
yX
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.Usando el
operator
móduloEsto 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í .
fuente