2011-05-22 15 views
19

¿Cómo se puede usar el argumento key para la función min para comparar una lista de 1 atributo de los objetos?Función min Python con una lista de objetos

Ejemplo

class SpecialNumber: 
    def __init__(self, i): 
     self.number = i 

li = [SpecialNumber(1), SpecialNumber(3), SpecialNumber(2)] 

Respuesta

36

http://docs.python.org/library/operator.html#operator.attrgetter

from operator import attrgetter 
min_num = min(li,key=attrgetter('number')) 

ejemplo de sesión interactiva:

>>> li = [SpecialNumber(1), SpecialNumber(3), SpecialNumber(2)] 
>>> [i.number for i in li] 
[1, 3, 2] 
>>> min_num = min(li,key=attrgetter('number')) 
>>> print min_num.number 
1 
26

Es:

min(li, key=lambda x: x.number) 

se necesita una función que acepta un SpecialNumber y devuelve su elemento.

+0

¿Es posible no devolver el elemento numérico devolviendo la clase 'SpecialNumber'? – Pwnna

+1

Devuelve el objeto 'SpecialNumber' por defecto. Para obtener el elemento más bajo, simplemente ejecute: 'min (li, clave = lambda x: x.number) .number' – viraptor

12

lo haría por razones imperiosas __cmp__

class SpecialNumber: 
    def __init__(self, i): 
     self.number = i 

    def __repr__(self): 
     return '<SpecialNumber(%d)>' % self.number 

    def __cmp__(self, other): 
     return cmp(self.number, other.number) 

li = [SpecialNumber(1), SpecialNumber(3), SpecialNumber(2)] 
print min(li) # <SpecialNumber(1)> 
+3

Tenga en cuenta que para Python 3.0 __cmp__ se ha ido. Entonces puede usar __lt__, __eq__ y el decorador functools.total_ordering en la clase para que funcione (o defina __lt__, __gt__, __le__, __ge__, __eq__, __ne__) –

+2

. Estos deberían haber sido dobles guiones bajos, aparentemente es un descuento para negrita. .. –

1

la versión getattr es más rápido

import random 
from operator import attrgetter 

class Test: 
    def __init__(self): 
     self.a = random.random() 

t = [Test() for i in range(10000)] 

%timeit min(t, key=lambda x: x.a) 
1000 loops, best of 3: 790 µs per loop 

%timeit min(t,key=attrgetter('a')) 
1000 loops, best of 3: 582 µs per loop 
Cuestiones relacionadas