sort() bei class, er macht was nur was? ;-)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
nihilist
User
Beiträge: 28
Registriert: Dienstag 13. Februar 2007, 07:02

Hallo ich habe mir auch ein Programm geschrieben, das Filme in eine Textdatei einliest.
Nun möchte ich diese auch sortieren, erstmal nur nach dem Filmtitel

Code: Alles auswählen

choice = 0
weiter = True
import pickle as p
moviefile = 'simmsave'

class film:
    def __init__(self, name, year,lend):
        self.name = name
        self.year = year
        self.lend = lend
        print 'Film %s initialisiert' % self.name

    def info(self):
        print '"%s" "%s" "%s" ' %(self.name, self.year, self.lend)

try:
    f = file(moviefile)
    gl = p.load(f)

except:
    ab = []
    f = file(moviefile, 'w')
    p.dump(ab, f)
    f.close()

def menu ():
    print 'Bitte Auswahl treffen'
    print '                           (1) Um die komplette Liste anzuzeigen'
    print '                           (2) Um einen Film zu suchen'
    print '                           (3) Um einen neuen Film hinzuzufuegen'
    print '                           (4) Um einen Film zu loeschen'
    print '                           (5) Liste Sortieren'
    print '                           (6) Um zu speichern'
    print '                           (0) Beenden'


menu()
while True:
    choice = int(raw_input('Was wollen sie machen? '))
    if choice == 1:
        print 'Titel        Jahr       Verliehen an'
        if len(gl) > 0:
            for item in gl:
                item.info()
        else:
            print 'Noch nichts in die Liste eingetragen'

    elif choice == 2:
        searchitem = raw_input('Nach was suchen?: ')
        for titel in gl:
            if titel.lend == searchitem:
                titel.info()
                break
        else:
            print 'Name nicht gefunden'


    elif choice == 3:
        new_name = raw_input('Bitte Filmnamen eingeben: ')
        new_year = raw_input('Bitte Erscheinungsjahr eingeben: ')
        new_lend = raw_input('Verliehen?: ')
        new_name = film(new_name, new_year, new_lend)
        gl.append(new_name)

    elif choice == 4:
        deleteitem = raw_input('Welchen Film loeschen? ')
        for film in gl:
            if film.name == deleteitem:
                gl.remove(film)
                print 'Film geloescht'
                break
        else:
            print 'Kann Film nicht finden'
    elif choice == 6:
        f = file(moviefile, 'w')
        p.dump(gl, f)
        f.close()
        print 'Filmliste gespeichert'


    elif choice == 0:
        save = raw_input('Speichern vor dem Beenden?(j/n) ')
        if save == 'j':
            f = file(moviefile, 'w')
            p.dump(gl, f)
            f.close()
            print 'Liste gespeichert, Programm Beendet'
            break
        elif save == 'n':
            print 'Beendet ohne zu speichern'
            break

    elif choice == 5:
            gl.sort()
            print 'Sortiert'
Nun, was soll ich sagen, er sortiert, aber nach keinem Schema, zumindest keines das ich bisher durchschaut habe.
Habe vorher ein ähnliches Programm geschrieben das allerdings nur die Namen in eine Textdatei eingelesen hat, und da hats mit
gl.sort()
funktioniert.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Naja, du versuchtst, eine Liste von selbstgebauten Klasses zu vergleichen. Aber woher soll Python wissen, nach was fuer Kriterien du Objekte dieser Klasse sortieren willst? Um zu sortieren, musst du Python mitteilen, was es bedeuten soll, dass zwei film-Objekte gleich sind, und wann ein film-Objekt groesser/kleiner ist als ein anderes... Dafuer kannst du die Vergleichs-Operatoren der film-Klasse ueberschreiben, schau mal hier: http://docs.python.org/ref/customization.html

PS: Klassennamen schreibt man gross
nihilist
User
Beiträge: 28
Registriert: Dienstag 13. Februar 2007, 07:02

danke dir,
ich denke das dürfte dann mit
__comp__
gehen.

Hast du vielleicht dazu ein kleines Beispiel zur Hand? Ich tu mich (noch) schwer mit dem Anwenden auf mein Programm.


P.S.
Klassenname ist jetzt gross... ;-)
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

Mal ne allgemeine Zwischenfrage, wenn wir schonmal bei .sort() sind... was genau ist das eigentlich fuer ein Algorithmus hinter .sort()? Ich weiß nur das er schweineschnell ist ^^
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Wenn man zum Beispiel eine Personenklasse nach dem name-Attribut sortiert haben will:

Code: Alles auswählen

#!/usr/bin/env python

class Person:

    def __init__(self, name, geburtstag):
            self.name = name;
            self.geburtstag = geburtstag

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

    def __str__(self):
        return "%s (%s)" % (self.name, self.geburtstag)


liste = [Person("Egon Meier", "1.1.1970"),
         Person("Maria Mueller", "7.7.1977"),
         Person("Otto Schmitt", "9.9.1959")]

liste.sort()

for entry in liste:
    print entry
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

nkoehring hat geschrieben:Mal ne allgemeine Zwischenfrage, wenn wir schonmal bei .sort() sind... was genau ist das eigentlich fuer ein Algorithmus hinter .sort()? Ich weiß nur das er schweineschnell ist ^^
Das ist Timsort, benannt nach Tim Peters. Näheres nachzulesen gibts hier: http://svn.python.org/view/python/trunk ... &view=auto
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

birkenfeld hat geschrieben: Das ist Timsort, benannt nach Tim Peters. Näheres nachzulesen gibts hier: http://svn.python.org/view/python/trunk ... &view=auto
Ah vielen Dank... :) Ich hab irgendwie nie was bei meinen Recherchen entdecken koennen.
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
nihilist
User
Beiträge: 28
Registriert: Dienstag 13. Februar 2007, 07:02

@ Rebecca
Danke dir, das hat geklappt, gar nicht so schwer wenn mans mal weiß...;-)

Ist es auch möglich zwei __cmp__ einzubinden? Damit man die Liste je nach Laune auch nach anderen Kriterien sortieren kann?
Aber das kann ich ja auch einfach mal versuchen....
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Da fallen mir gerade 2 Varianten ein:

Code: Alles auswählen

#1. Variante
import operator
liste.sort(key=operator.attrgetter('geburtstag'))

for entry in liste:
    print entry

#2. Variante
def cmp2(this, other):
    return cmp(this.geburtstag, other.geburtstag)
liste.sort(cmp=cmp2)

for entry in liste:
    print entry
Für beide Varianten bräuchtest du die __cmp__-Methode nicht mehr.

Bei der ersten kannst du mit operator.attrgetter ein Attribut nehmen um zu vergleichen.

Bei der zweiten Variante eine externe compare-Funktion, bei der auch komplexere Vergleiche gehen (zuerst nach Namen dann nach Geburtstag sortieren).

Gruss
Antworten