Tengo una lista de objetos de Python que me gustaría ordenar por un atributo de los propios objetos. La lista se ve así:
>>> ut
[<Tag: 128>, <Tag: 2008>, <Tag: <>, <Tag: actionscript>, <Tag: addresses>,
<Tag: aes>, <Tag: ajax> ...]
Cada objeto tiene un recuento:
>>> ut[1].count
1L
Necesito ordenar la lista por número de conteos descendentes.
He visto varios métodos para esto, pero estoy buscando las mejores prácticas en Python.
Respuestas:
Más sobre la clasificación por teclas .
fuente
Una forma que puede ser más rápida, especialmente si su lista tiene muchos registros, es usarla
operator.attrgetter("count")
. Sin embargo, esto podría ejecutarse en una versión previa al operador de Python, por lo que sería bueno tener un mecanismo de reserva. Es posible que desee hacer lo siguiente, entonces:fuente
self.__dict__ = {'some':'dict'}
después del__init__
método). Sin embargo, no sé por qué podría ser diferente.__dict__
. Tenga en cuenta que "un objeto que tiene atributos agregados dinámicamente" y "establecer el__dict__
atributo de un objeto " son conceptos casi ortogonales. Lo digo porque su comentario parece implicar que establecer el__dict__
atributo es un requisito para agregar atributos dinámicamente.operator.attrgetter
, podría proporcionar una función con cualquier nombre de propiedad y devolver una colección ordenada.Los lectores deben notar que la clave = método:
es muchas veces más rápido que agregar operadores de comparación enriquecidos a los objetos. Me sorprendió leer esto (página 485 de "Python in a Nutshell"). Puede confirmar esto ejecutando pruebas en este pequeño programa:
Mis pruebas, muy mínimas, muestran que el primer tipo es más de 10 veces más lento, pero el libro dice que en general es solo 5 veces más lento. La razón que dicen se debe al algoritmo de clasificación altamente optimizado utilizado en python ( timsort ).
Aún así, es muy extraño que .sort (lambda) sea más rápido que el antiguo .sort (). Espero que arreglen eso.
fuente
__cmp__
es equivalente a llamar.sort(cmp=lambda)
, no.sort(key=lambda)
, por lo que no es extraño en absoluto.longList2.sort(cmp = cmp)
. Probé esto y funcionó casi igual que.sort()
. (También: tenga en cuenta que el parámetro de ordenación "cmp" se eliminó en Python 3.)Enfoque orientado a objetos
Es una buena práctica hacer que la lógica de clasificación de objetos, si corresponde, sea una propiedad de la clase en lugar de incorporarse en cada caso en el que se requiere el orden.
Esto garantiza la coherencia y elimina la necesidad de código repetitivo.
Como mínimo, debe especificar
__eq__
y las__lt__
operaciones para que esto funcione. Entonces solo úsalosorted(list_of_objects)
.fuente
__eq__
y cuáles__lt__
son los requisitos mínimos de implementación?•The sort routines are guaranteed to use __lt__() when making comparisons between two objects...
fuente
Se parece mucho a una lista de instancias de modelo ORM de Django.
¿Por qué no ordenarlos en una consulta como esta?
fuente
Agregue operadores de comparación enriquecidos a la clase de objeto, luego use el método sort () de la lista.
Vea una rica comparación en python .
Actualización : aunque este método funcionaría, creo que la solución de Triptych se adapta mejor a su caso porque es mucho más simple.
fuente
Si el atributo por el que desea ordenar es una propiedad , puede evitar importar
operator.attrgetter
y utilizar elfget
método de la propiedad .Por ejemplo, para una clase
Circle
con una propiedadradius
podríamos ordenar una listacircles
por radios de la siguiente manera:Esta no es la característica más conocida, pero a menudo me ahorra una línea con la importación.
fuente