Tengo una lista de objetos personalizados que tienen dos atributos (importantes), un código de estado (TX, CA, NY, etc) y un nivel de grado (PK = preK, ES = Escuela Primaria, etc). Tengo que ordenar esta lista por grado, a continuación, en orden alfabético por código de estado. Lo que tengo ahora es la siguiente:
class myObject:
def __init__(self, state, grade):
self.state = state
self.grade = grade
myObjects = []
myObjects.append(myObject("KY", "HS"))
myObjects.append(myObject("AL", "ES"))
myObjects.append(myObject("NY", "PK"))
myObjects.append(myObject("CA", "PK"))
possibleGrades = ["PK", "K", "ES", "MS", "HS"]
myObjects.sort(key=lambda x: (x.grade, x.state))
for x in myObjects:
print("Grade: {}, State: {}".format(x.grade, x.state))
salida:
Grade: ES, State: AL
Grade: HS, State: KY
Grade: PK, State: CA
Grade: PK, State: NY
Lo que quiero es:
Grade: PK, State: CA
Grade: PK, State: NY
Grade: ES, State: AL
Grade: HS, State: KY
Lo que tengo ordena myObjects por grado y entonces el estado, pero puse la escuela primaria es antes de Pre-K porque no puedo encontrar la manera de especificar el orden de clasificación para ser possibleGrades. Sé que hay una manera de uso .index como se usa aquí https://www.geeksforgeeks.org/python-sort-list-according-to-other-list-order/ a ordenar por una orden de encargo, pero no puedo 't encontrar la manera de hacer eso con los atributos de un objeto. Parece que debe ser algo como:
standards.sort(key=lambda x: (x.grade, x.state) possibleGrades.index(x))
o, en dos pasadas:
standards.sort(key=lambda x: x.grade possibleGrades.index(x))
standards.sort(key=lambda x: x.state)
Pero eso no funciona. Sé que un género con varias pasadas puede para ordenar por más de un atributo, no estoy atado a hacerlo en una sola pasada, que es sólo la más reciente iteración y me parece el tipo de cosa que Python podría ser capaz de hacer. peor de los casos, podría escribir una función entera con def a solucionar el problema, pero antes de hacer eso, ¿hay alguna manera más Pythonic a solucionar el problema con lambdas que estoy tratando de hacer?
Prueba esto:
myObjects.sort(key=lambda x: (possibleGrades.index(x.grade), x.state))
Esto ordena por el índice de pendiente de la lista possibleGrades
en primer lugar, a continuación, según el estado.
Según lo sugerido por @a_guest también se podría construir un diccionario de la lista, sobre todo si es una lista grande, y hacer un O (1) las operaciones de búsqueda. A continuación, el código se verá así:
grades = {g: i for i, g in enumerate(possibleGrades)}
myObjects.sort(key=lambda x: (grades[x.grade], x.state))