Tengo una lista de listas:
[[12, 'tall', 'blue', 1],
[2, 'short', 'red', 9],
[4, 'tall', 'blue', 13]]
Si quisiera ordenar por un elemento, digamos el elemento alto / bajo, podría hacerlo a través de s = sorted(s, key = itemgetter(1))
.
Si quería para ordenar por tanto alto / bajo y el color, que podría hacer la clase dos veces, una para cada elemento, pero ¿hay una forma más rápida?
sort
. Es decir,sorted([(4, 2), (0, 3), (0, 1)]) == [(0, 1), (0, 3), (4, 2)]
.Respuestas:
Una tecla puede ser una función que devuelve una tupla:
O puede lograr lo mismo usando
itemgetter
(que es más rápido y evita una llamada a la función Python):Y observe que aquí puede usar en
sort
lugar de usarsorted
y luego reasignar:fuente
-
para enteros)revrse=True
solo ax[1]
eso es posible?s = sorted(s, key = operator.itemgetter(2))
luego por el primarios = sorted(s, key = operator.itemgetter(1), reverse=True)
No es ideal, pero funciona.-1
.No estoy seguro de si este es el método más pitónico ... Tenía una lista de tuplas que necesitaba clasificarse primero por valores enteros descendentes y segundo alfabéticamente. Esto requería invertir el orden entero pero no el orden alfabético. Aquí estaba mi solución: (sobre la marcha en un examen, por cierto, ni siquiera sabía que podía 'anidar' funciones ordenadas)
fuente
b = sorted(a, key = lambda x: (-x[1], x[0]))
cuál es más visible en qué criterio se aplica primero. En cuanto a la eficiencia, no estoy seguro, alguien necesita tiempo.Varios años más tarde a la fiesta pero quiero tanto especie en 2 criterios y uso
reverse=True
. En caso de que alguien más quiera saber cómo, puede ajustar sus criterios (funciones) entre paréntesis:fuente
Parece que podrías usar un en
list
lugar de untuple
. Esto se vuelve más importante, creo, cuando estás tomando atributos en lugar de 'índices mágicos' de una lista / tupla.En mi caso, quería ordenar por múltiples atributos de una clase, donde las claves entrantes eran cadenas. Necesitaba una clasificación diferente en diferentes lugares, y quería una clasificación predeterminada común para la clase principal con la que los clientes interactuaban; solo tener que anular las 'claves de clasificación' cuando realmente 'lo necesitaba', pero también de una manera que pudiera almacenarlas como listas que la clase podría compartir
Así que primero definí un método auxiliar
entonces para usarlo
Esto usará la función lambda generada, clasificará la lista
object.attrA
y luegoobject.attrB
suponiendo queobject
tenga un captador correspondiente a los nombres de cadena proporcionados. Y el segundo caso se resolvería paraobject.attrC
entoncesobject.attrA
.Esto también le permite exponer potencialmente las opciones de clasificación externas para que un consumidor las comparta por igual, una prueba unitaria, o para que le digan cómo quieren que se realice la clasificación para alguna operación en su API solo tiene que darle una lista y no acoplándolos a su implementación de back-end.
fuente
Aquí hay una manera: básicamente reescribe su función de clasificación para tomar una lista de funciones de clasificación, cada función de clasificación compara los atributos que desea probar, en cada prueba de clasificación, observa y ve si la función cmp devuelve un retorno distinto de cero si es así, rompa y envíe el valor de retorno. Lo llamas llamando a un Lambda de una función de una lista de Lambdas.
Su ventaja es que solo pasa a través de los datos, no una especie de clasificación anterior como lo hacen otros métodos. Otra cosa es que se ordena en su lugar, mientras que ordenado parece hacer una copia.
Lo usé para escribir una función de clasificación, que clasifica una lista de clases donde cada objeto está en un grupo y tiene una función de puntuación, pero puede agregar cualquier lista de atributos. Tenga en cuenta el uso no lambda, aunque hack de una lambda para llamar a un setter. La parte de rango no funcionará para una variedad de listas, pero sí lo hará.
Aquí hay una manera de clasificar una lista de objetos
fuente