Liste auf gleiche Elemente prüfen

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.
Mars
User
Beiträge: 10
Registriert: Freitag 14. Mai 2004, 16:29

Liste auf gleiche Elemente prüfen

Beitragvon Mars » Samstag 15. Mai 2004, 14:37

Hallo, ich brauche eine Funktion, die prüft, ob in zwei Listen die gleichen Elemente sind -- unabhängig von der Reihenfolge. Dabei kommt Sortieren nicht in Frage, weil das nur eine Modellfunktion ist und letztlich die Elementen Instanzen einer Klasse sein werden und der Test auf Gleichheit auch durch einen anderen Funktionsaufruf ersetzt wird. Ich habe keine Lust ein spezielles Sortierkriterium zu definieren.

Code: Alles auswählen

def gleich(l1,l2):
    if len(l1) != len(l2):
        return False
    l2c = l2[:]
    for x in l1:
        for y in l2c:
            if x == y:
                l2c.remove(y)
                break
    return not l2c
Weiß jemand einen eleganteren Weg als meinen?
Benutzeravatar
fs111
User
Beiträge: 170
Registriert: Samstag 15. November 2003, 11:42
Kontaktdaten:

Beitragvon fs111 » Samstag 15. Mai 2004, 15:03

http://python.sandtner.net/viewtopic.php?t=1564 sollte Dir helfen.

Grüße fs111
Benutzeravatar
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Beitragvon Dookie » Samstag 15. Mai 2004, 15:05

Hi Mars,

Code: Alles auswählen

def gleich(l1,l2):
    if len(l1) != len(l2):
        return False
    for item in l1:
        if l1.count(item) != l2.count(item): # if item not in l2: #wenn die Anzahl gleicher egal ist
            break
    else: #for
        return True
    return False

Die geänderte Vergleichsfunktion würde ich dann als Metode __eq__ der Klasse der Instanzen implementieren. Damit müsste die count-Methode der Listen auch funktionieren.


Gruß

Dookie
Mars
User
Beiträge: 10
Registriert: Freitag 14. Mai 2004, 16:29

Beitragvon Mars » Samstag 15. Mai 2004, 15:35

fs111, das funktioniert wahrscheinlich nicht, wenn man davon ausgeht, dass mehrere gleiche Elemente aber in unterschiedlicher Zahl vorhanden sind:

Code: Alles auswählen

>>> l1 = [1,1,1,2,2,2]
>>> l2 = [2,2,1,1,1,1]
>>> [i for i in l2 if not i in l1]
[]
>>> [i for i in l1 if not i in l2]
[]

--> beide Differenzlisten sind leer; die Listen aber nicht "gleich" für meinen Zweck.

Dookie, die count-Methode verkürzt das ganze schon ein Stück, wenn ich Gleichheit für meine Klasse definiert hätte. Meine Klasse ist aber im wesentlichen ein Paar von floats, für das Gleichheit gefährlich ist. Meine Funktion benutze ich eigentlich nur im Rahmen eines Unittests, wo ich auf ungefähre Gleichheit prüfe, womit ich aber meine Klasse nicht ausstatten will.

Ich glaube, für diesen Fall lasse ich die Funktion, wie sie ist. Wenn ich das gleiche mal mit Integern oder so mache, greife ich auf die count-Methode zurück.

Vielen Dank für die Hilfe! Dieses Forum gefällt mir. :)
Benutzeravatar
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Beitragvon Dookie » Samstag 15. Mai 2004, 15:51

Hi Mars,

schön daß Dir das Forum gefällt :)
Hier mal eine Klasse für floats, wo die Genauigkeit bei Vergleichen in der Klasse definiert ist:

Code: Alles auswählen

class ufloat(float):
    unit = 1.0e-5
    def __cmp__(self, other):
        if abs(self-other) < self.unit:
            return 0
        else:
            return super(ufloat, self).__cmp__(other)


Gruß

Dookie
Mars
User
Beiträge: 10
Registriert: Freitag 14. Mai 2004, 16:29

Beitragvon Mars » Samstag 15. Mai 2004, 18:10

Das Blöde ist nur, dass so eine festgelegte Genauigkeit eben nur für bestimmte Größenordnungen gültig ist. Fließkommazahlen bestehen eben aus Mantisse und Exponent. Für sehr große Zahlen hilft "unit = 1.0e-5" eben nicht. Man müsste eigentlich eine gewisse Anzahl signifikanter Bits vergleichen.

Im Moment benutze ich assertAlmostEqual aus unittest, das aber das gleiche Problem hat, wie ich nach kurzem Quelltextstudium feststellen konnte. Nun ja, für meine bescheidenen Zwecke reicht es wohl, meistens habe ich eh Zahlen zwischen -1 und 1. :)

Wer ist online?

Mitglieder in diesem Forum: martinjo