Seite 1 von 1

Vergleich von Listen

Verfasst: Donnerstag 10. Dezember 2009, 21:15
von Accredo
Hallo an alle.Ich sitze schon lange an einer Aufgabe und bin langsam am verzweifeln.Wahrscheinlich ist das wieder mal eigentlich total leicht,aber ich bekomms irgendwie nicht hin.Wäre für jeden Tip oder Link oder soetwas dankbar.

Mein problem ist das ich zwei verschachtelte Listen habe,die ungefähr so aussehen:
1.Liste
[[00-1207,01-1308],[08-4567,07-1234,05-3423]]
2.Liste
[[01-1308,00-1207],[07-1234,08-4567,05-3423]]

oder in der Form um es anschalicher zu machen:
test=[[otto,alex,marco],[lilli,sandra]]
test1=[[sandra,lilli],[alex,otto,marco]]

ich möchte nun gerne beide Listen vergleichen.In diesem Fall sind die listen ja identisch obwohl die Anordnung sowohl der Listenelemente in der großen Liste als auch in den einzelnen Listen vertauscht sind.Deshalb muss ich irgendwie jede einzelne Position vergleichen als auch jede gesamte Liste miteinander.
Ich hab schon versucht mehrere for-schleifen zu machen nur irgendwie geht das so nicht.:-(
Das sah bei mir so aus(ist aber bestimmt eh falsch):

Code: Alles auswählen

for i in range (0,len(test)):
    for j in range (0,len(test1)):
        for n in range(0,len(test[i])):
            for m in range (0, len(test1[j])):
                if test[i][n]!= test1[j][m]:
                    print [i]
Vielleicht kann mir jemand nen tip oder ne Seite oder soetwas geben.Danke im vorraus

Verfasst: Donnerstag 10. Dezember 2009, 22:08
von derdon

Code: Alles auswählen

>>> test=[['otto', 'alex', 'marco'], ['lilli', 'sandra']] 
>>> test1=[['sandra', 'lilli'], ['alex', 'otto', 'marco']]
>>> sorted(sorted(list_) for list_ in test)
[['alex', 'marco', 'otto'], ['lilli', 'sandra']]
>>> sorted(sorted(list_) for list_ in test1)
[['alex', 'marco', 'otto'], ['lilli', 'sandra']]
Reicht das als Denkanstoß? Funktioniert natürlich nur, wenn die Listen nicht tiefer verschachtelt sind.

Verfasst: Donnerstag 10. Dezember 2009, 22:11
von gkuhl
Hallo,

wieso benutzt du so eine schwer durchschaubare Datenstruktur? Es wäre vermutlich hilfreich, wenn du das tatsächliche Problem beschreiben würdest. Eine verständliche Struktur macht es dir auch leichter in ein paar Jahren den Code noch zu verstehen.

Grüße
Gerrit

Verfasst: Donnerstag 10. Dezember 2009, 22:12
von dev
ohne jetzt mal über Effizienz nachzudenken:
  1. die Listen auf einen Level bringen -> z.B. list flatten
  2. sortieren
  3. vergleichen
Ciao,
dev

Verfasst: Donnerstag 10. Dezember 2009, 23:19
von Accredo
Hallo,
erst mal vielen lieben Dank für die Hilfe.
@derdon:
Das mit dem sortieren ist schon mal ein super Tip, so kann ich wenigstens schon einmal in der Shell schauen, ob die beiden Listen relativ gleich sind. Das schau ich mir nochmal genauer an. Vielen Dank.

@gkuhl:
Ich habe eigentlich zwei verschiedene Datensätze (aus einer Analyse) die aus ca.500 Listen bestehen. Können sich aber in den Positionen verändern, sowohl in der Anordung wo die Listen in der Liste stehen, als auch in den eigenen Listen selbst. (So wie ich das versucht habe in dem Beispiel zu zeigen, allerdings sind das im Beispiel ja nur 2 Listen in der großen Liste und nicht 500). Diese Datensätze habe ich erstmal aus 2 Files eingelesen und in diese Form:

[[01-1308,00-1207],[07-1234,08-4567,05-3423]]

formatiert, da es bei den Files wichtig ist das die Werte:

(z.B:[07-1234,08-4567,05-3423])

einzeln in einer Liste stehen, es ist deshalb nicht möglich alles in eine große Liste zu schreiben, weil jede einzelne Liste die selben Elemente haben muß und halt auch insgesamt die selben Listen im File sein sollen. Eigentlich brauch ich dann als Ausgabe die Daten (Listen) die nicht in einem der Files drin sind (deshalb der Vergleich).
Falls das unverständlich war, tut mir das leid, ich find das schwer zu erklären :-(

@dev das flatten schau ich mir auch mal an. Vielen Dank, die Reihenfolge sieht gut aus.

@alle: Gibt es den auch soetwas wie
test.issubset(test1)
für verschachtelte Listen? Oder muß ich dann da irgenwie ne schleife schreiben? Sorry für die dummen Fragen bin noch Anfänger.

Verfasst: Donnerstag 10. Dezember 2009, 23:45
von EyDu
Accredo hat geschrieben:@alle: Gibt es den auch soetwas wie
test.issubset(test1)
für verschachtelte Listen? Oder muß ich dann da irgenwie ne schleife schreiben? Sorry für die dummen Fragen bin noch Anfänger.
Du solltest vielleicht einfach Mengen verwenden.

Übrigens kann man direkt über Elemente einer Liste iterieren. Die ganzen

Code: Alles auswählen

for n in range(0,len(liste)):
    print liste[n]
kannst du durch

Code: Alles auswählen

for element in liste:
    print element
ersetzen.

Verfasst: Freitag 11. Dezember 2009, 00:50
von jerch
Accredo hat geschrieben:...
Eigentlich brauch ich dann als Ausgabe die Daten (Listen) die nicht in einem der Files drin sind (deshalb der Vergleich).
Falls das unverständlich war, tut mir das leid, ich find das schwer zu erklären :-(
Ja, das ist sehr unverständlich. Wo kommen jetzt die Daten her, die nicht in Files stehen, obwohl Du vorher alles aus Files genommen hast?

Brauchst Du vllt. die Schnittmenge aller Listen-"mengen"? Oder das Komplement?
Wie EyDu schon anmerkte, ist dann set() wohl was für Dich.

@zum "flatten":
Die Sublisten kannst Du natürlich nur flatten, wenn diese Aufteilung keine relevante Information beinhaltet. (ist mir aus Deiner Beschreibung nicht ganz klar)

Bitte beschreibe doch nochmal ausführlicher die Ausgangslage und das gewünschte Ergebnis, die vermeintlichen Zwischenlösungen stiften eher Verwirrung.

Grüsse, jerch

Verfasst: Sonntag 13. Dezember 2009, 15:11
von Accredo
Hallo,
Mein eigentliches Problem besteht in dem Vergleich von zwei Listen. Als Ausgabe möchte ich gerne die „unterschiedlichen“ Elemente bekommen.
Es muß allerdings jede Position der einen Liste mit jeder Position der anderen Liste verglichen werden.
Also praktisch wenn die Listen so z.B. so aussehen:
1.Liste:
Liste1=[[Alex,Otto],[Marion,Norbert,Otto],[Paul,Patrick],[Rudi,Silvie]]
2.Liste:
Liste2=[[Alex,Otto], [Marion,Norbert,Otto],[Rudi,Silvie]]

Dann hätten die Listen einen Unterschied:
[Paul,Patrick]
Diesen würde ich dann gerne ausgegeben bekommen. Da meine eigentlichen Listen ca. 500 Elemente haben kann man dieses nicht mehr gut überblicken.
Das ist denk ich mal was ganz simples,ich komm nur nicht drauf.
Wenn ich z.B eine Schleife schreibe:

Code: Alles auswählen

for i in liste1:
    for j in liste2:
        if liste1[i]!= liste2[j]:
            print "No Match",[i]
bekomme ich nicht das gewünschte Ergebnis.
Ich weiß irgendwie nicht wie:-(

Verfasst: Sonntag 13. Dezember 2009, 15:34
von Accredo
vielleicht ist es auch wichtig das ich die listen vorher sortiert habe.

liste1=sorted(sorted(list_) for list_ in output)
liste2=sorted(sorted(list_) for list_ in output2)

Verfasst: Sonntag 13. Dezember 2009, 15:43
von Hyperion
Accredo hat geschrieben: Das ist denk ich mal was ganz simples,ich komm nur nicht drauf.
Wenn ich z.B eine Schleife schreibe:

Code: Alles auswählen

for i in liste1:
    for j in liste2:
        if liste1[i]!= liste2[j]:
            print "No Match",[i]
bekomme ich nicht das gewünschte Ergebnis.
Ich weiß irgendwie nicht wie:-(
OMG. Hast Du mal das Tutorial durchgearbeitet?
Bevor ich hier so viel posten würde, hätte ich mir mal angesehen, was in i und j drin steht ;-)

Verfasst: Sonntag 13. Dezember 2009, 15:45
von Hyperion
Accredo hat geschrieben:Hallo,
Mein eigentliches Problem besteht in dem Vergleich von zwei Listen. Als Ausgabe möchte ich gerne die „unterschiedlichen“ Elemente bekommen.
Ist die Position der Elemente denn wichtig?
Es muß allerdings jede Position der einen Liste mit jeder Position der anderen Liste verglichen werden.
Weil die Position wichtig ist, oder weil Du das so willst?
Wären also folgende Listen nach Deiner Definition unterschiedlich:

Code: Alles auswählen

a = [1, 2]
b = [2, 1]
Wenn ja, wie sähe das Ergebnis aus?

Wenn nein: Da gab es hier schon genügend Anregungen...

Verfasst: Sonntag 13. Dezember 2009, 20:59
von ms4py
Vielleicht willst du dir auch mal numpy anschauen, damit kannst du 2-D Arrays erstellen und auf Gleichheit testen:

Code: Alles auswählen

>>> from numpy import *
>>> a = zeros((2,3))
>>> b = zeros((2,3))
>>> a == b
array([[ True,  True,  True],
       [ True,  True,  True]], dtype=bool)
>>> all(a==b)
True
>>> a[1,0] = 1
>>> all(a==b)
False
>>> a
array([[ 0.,  0.,  0.],
       [ 1.,  0.,  0.]])

Verfasst: Sonntag 13. Dezember 2009, 21:24
von jerch
Accredo hat geschrieben:...
1.Liste:
Liste1=[[Alex,Otto],[Marion,Norbert,Otto],[Paul,Patrick],[Rudi,Silvie]]
2.Liste:
Liste2=[[Alex,Otto], [Marion,Norbert,Otto],[Rudi,Silvie]]

Dann hätten die Listen einen Unterschied:
[Paul,Patrick]
...
Das Beispiel könntest Du mit Sets umsetzen:

Code: Alles auswählen

>>> Liste1=[['Alex','Otto'],['Marion','Norbert','Otto'],['Paul','Patrick'],['Rudi','Silvie']]
>>> Liste2=[['Alex','Otto'],['Marion','Norbert','Otto'],['Rudi','Silvie']]
>>> set(map(tuple, Liste1)).difference(set(map(tuple, Liste2)))
set([('Paul', 'Patrick')])
Das ganze funktioniert nur, wenn eine spez. Subliste nur einmal vorkommt, weitere Vorkommen werden von set([]) "verschluckt". Desweiteren arbeitet set nur mit hashable Typen (list-->tuple).

Mit Listen ginge es auch:

Code: Alles auswählen

l1 = []
l2 = liste2[:]
for i in liste1:
    try:
        l2.remove(i)
    except ValueError:
        l1.append(i)
l1 und l2 enthalten dann die nur noch die Elemente, die in der jeweils anderen Liste nicht vorkommen.

Vllt. hilft Dir das irgendwie weiter.

Verfasst: Montag 14. Dezember 2009, 20:47
von Accredo
@Hyperion:
ich muß zugeben das Tutorial hab ich noch nicht komplett durchgesehen,werde das jetzt mal nachholen..danke nochmal für den Denkanstoss :-)
@ice2k3:
numpy werde ich mir auch mal anschauen.Danke auch für diesen Tip.
@jerch:
Echt super cool!!Vielen lieben Dank, so funktioniert das ganze.Und das sieht nach so einer simplen Lösung aus.Das hat mir echt super geholfen!
Ich wollte dich nochmal fragen verstehe ich das Programm richtig?
Du gehst mit i durch die erste Liste durch und enfernst alle Elemente aus Liste1 in der Liste2.
Somit hast du in der Liste2 nur die Elemente die nicht in Liste1 vorkommen.
Dann packst du die Elemente aus der Liste1 in die Liste1.
Somit hast du in der Liste 1 nur alle Elemente die nicht in der Liste 2 vorkommen?Oder?
Nochmals danke

Verfasst: Montag 14. Dezember 2009, 21:23
von jerch
Accredo hat geschrieben: Ich wollte dich nochmal fragen verstehe ich das Programm richtig?
Du gehst mit i durch die erste Liste durch und enfernst alle Elemente aus Liste1 in der Liste2.
Somit hast du in der Liste2 nur die Elemente die nicht in Liste1 vorkommen.
Genau.
Accredo hat geschrieben:Dann packst du die Elemente aus der Liste1 in die Liste1.
Somit hast du in der Liste 1 nur alle Elemente die nicht in der l2 vorkommen?...
Hm, da versteht ich Dich nicht. Die Listensache ist eher wie eine Bedingung zu verstehen: Wenn Element i aus Liste1 nicht löschbar ist in Liste2, hänge es an l1 an. Damit hast Du auch alle Überzähligen aus Liste1.
Also eigentlich so:

Code: Alles auswählen

l1 = []
l2 = liste2[:]
for i in liste1:
    if i in l2:
        l2.remove(i)
    else:
        l1.append(i)
Allerdings wollte ich den zusätzlichen Lookup in l2 vermeiden, deshalb die bedingte Chose mittels Exception.

Alle diese von mir gezeigten Versionen funktionieren nur in Deinem Sinne, wenn die Listen vorsortiert sind. Ich glaube, dass da noch optimiert werden könnte (z.B. mittels flatten), aber leider werde ich aus Deinen Zusatzinfos einfach nicht schlau.

Grüsse, jerch

PS: Bei der Exceptionsversion fehlt übrigens noch der Fehlertyp, habs oben mal ergänzt.