2013-08-01 16 views
13

To jest kod, który napisałem do tej pory, a punktem programu jest odczytanie 20 osób z pliku, a następnie przypisanie im ich atrybutów, a następnie znormalizowanie ich wartości z danych wprowadzonych przez użytkownika.Pobierz obiekt z wartością atrybutu max na liście obiektów

class One: 
    def __init__(self): 
     self.attrOne =() 
     self.attrTwo =() 
     self.attrThree =() 
     self.attrFour =() 
     self.attrFive=() 
     self.attrSix =() 
     self.attrSeven =() 
     self.attrEight =() 
     self.attrNine =() 


class Two: 

    def __init__(self): 
     self.allPersons = [] 

    def importFromList(self, filename): 
     file= open(filename, "rU") 
     for line in file: 
      partOfList = line.split()       
      x = Partner() 
      x.attrOne = partOfList[0] 
      x.attrTwo = partOfList[1] 
      x.attrThree = partOfList[2] 
      x.attrFour = partOfList[3] 
      x.attrFive = partOfList[4] 
      x.attrSix = partOfList[5] 
      x.attrSeven = partOfList[6] 
      x.attrEight= partOfList[7] 
      x.attrNine = partOfList[8] 
      self.addPerson(x) 
     file.close() 

def addPerson(self, x): 
    self.allPersons.append(x) 

Co Zastanawiam się jak pętla poprzez atrybuty osoby, które są umieszczone w wykazie allPersons, a następnie porównać je z siebie, aby dowiedzieć się wartość max. To, co starałem tak daleko, ale nie mogę zmusić go do pracy

def getMaxValue(self): 
    o = One() 
    for eachPartner in self.allPartners: 
     maxValuesAttrOne = max(O.attrOne)) 

Wszystkie pomoc będzie mile widziane, i jestem otwarty na nowe rozwiązania, także sobie wyobrazić metoda importFromList nie jest najbardziej skuteczny jeden, więc jeśli masz jakieś zastrzeżenia, jestem gotów słuchać i uczyć się!

+0

Czy istnieje powód, dla którego masz 9 oddzielnych atrybutów o nazwie 'attrOne' do' attrNine' zamiast, powiedzmy, pojedynczy atrybut, który jest listą 9 wartości, czy też odwzorowanie dyktujące nazw 9 na wartości? – abarnert

+0

Ponadto, dlaczego klasa 'One' ma 9 atrybutów wszystkich ustawionych na pustą krotkę, natomiast' Partner' ma 9 atrybutów o tych samych nazwach, z których każda jest ustawiona na łańcuch? To wydaje się być receptą na zamieszanie ... – abarnert

+0

Atrybuty to definicje osoby, na przykład imię, wiek i bogactwo. Rename je przed opublikowaniem tutaj. Czy lepiej jest używać self.name = nazwa zamiast pustej krotki? Co masz na myśli, mówiąc, że mając dyktujące odwzorowanie 9 nazw na wartości, nie przekopaliśmy się na temat korzystania ze słowników w trakcie, który zrobiłem, ale chciałbym, aby był to przykł[email protected] – Filip

Odpowiedz

34

max() przyjmuje parametr key, funkcję, która po przejściu jednego z obiektów zwraca wartość, za pomocą której można je porównać.

Zastosowanie operator.attrgetter() aby uzyskać tę wartość:

from operator import attrgetter 

max(self.allPartners, key=attrgetter('attrOne')) 

ta zwraca obiekt pasujący na które ten atrybut jest maksymalna. Jeśli chciał przechowywać tylko tę wartość maksymalną sam, masz dwie opcje:

  • przybrać atrybut ze zwróconego obiektu:

    max(self.allPartners, key=attrgetter('attrOne')).attrOne 
    
  • minąć te atrybuty zamiast max() z wyrażeniem generatora :

    max(p.attrOne for p in self.allPartners) 
    

Jeśli okaże się, że trzeba zamówić One klas w różnych kierunkach o tym samym atrybucie raz po raz (aby znaleźć minimum, maksimum, posortuj je itp.), Możesz również ustawić klasę do porządkowania.

Aby to zrobić, musisz wprowadzić z jakiegoś z basic customization hooks Python będzie szukać. Z pewnym dodatkowym oszustwa, można uciec tylko z niższego potem i wynosi operacji, a za pomocą funtools.total_ordering class decorator:

from functools import total_ordering 

@total_ordering 
class One: 
    # ... 
    def __lt__(self, other): 
     if not isinstance(other, type(self)): return NotImplemented 
     return self.attrOne < other.attrOne 

    def __eq__(self, other): 
     if not isinstance(other, type(self)): return NotImplemented 
     return self.attrOne == other.attrOne 

Teraz klasa One jest można zamówić, wyłącznie na podstawie attrOne; w przypadku funkcji max() oznacza to, że można całkowicie zrzucić parametr key.

+0

wypróbowałem rozwiązanie itemgetter i ciągle otrzymuję ten błąd – Filip

+0

To dlatego, że w mojej odpowiedzi wystąpił błąd ; powinno to być 'attrgetter', a nie' itemgetter'. Mea culpa! –

+2

Dla rekordu, 'itemgetter' służy do dostępu do artykułu. 'słownik ['somekey']' lub 'alist [1]' są przykładami dostępu do elementów, a dla nich można użyć wywołania 'itemgetter'. Natomiast dostęp do atrybutów to 'someobject.attrOne', a do tego użyjesz' attrgetter'. Próby użycia 'itemgetter' w każdym razie spowodowałyby' TypeError', ponieważ twoja klasa nie definiuje metody '__getitem__' ... –

Powiązane problemy