2010-09-01 22 views
4

Je suis nouveau sur Python et j'adore la fonction min.Python - Minimum d'une liste de variables d'instance

>>>min([1,3,15]) 
0 

Mais si j'ai une liste des cas, et ils ont tous une variable nommée number?

class Instance(): 
    def __init__(self, number): 
     self.number = number 

i1 = Instance(1) 
i2 = Instance(3) 
i3 = Instance(15) 
iList = [i1,i2,i3] 

Dois-je vraiment quelque chose comme

lowestI = iList[0].number 
for i in iList: 
    if lowestI > iList[i].number: lowestI = iList[i].number 
print lowestI 

je ne peux pas utiliser min dans une belle façon pythonique?

+4

Votre fonction 'min' doit être cassé ...' min ([1,3,15]) 'donne moi '1';) –

Répondre

13

La façon POO serait de mettre en œuvre __lt__:

class Instance(): 
    def __init__(self, number): 
     self.number = number 

    def __lt__(self, other): 
     return self.number < other.number 
     # now min(iList) just works 

Une autre façon est

imin = min(iList, key=lambda x:x.number)

Des fonctions telles que sort, min, max prennent tous un argument key. Vous donnez une fonction qui prend un objet et renvoie tout ce qui doit représenter cet élément lorsque vous le comparez.

10
from operator import attrgetter 
min(iList, key = attrgetter("number")) 

Le même argument key travaille également avec sort, pour mettre en œuvre l'idiome undecorate tri décorez Pythonically.

+1

' min (iList, key = attrgetter ("nombre")) ' – leoluk

+0

@leoluk: merci! – katrielalex

+4

rock attrgetter et itemgetter - beaucoup de fonctions lambda peuvent être éliminées en les utilisant. Ils sont plus rapides que lambda et IMHO plus facile à lire. –

1
min(iList, key=lambda inst: inst.number) 
+0

Oups, trop tard. – leoluk

5

syntaxe Générateur:

min(i.number for i in iList) 

key fonction:

min(iList, key=lambda i: i.number) 
+0

'key' est meilleur que generator car il garde la référence à l'instance. – leoluk