geschachtelte for-loops

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
Lastalda
User
Beiträge: 10
Registriert: Dienstag 25. Mai 2010, 14:29

Ich versuche gerade, ein Script zum Vergleichen von Sequenzpaaren zu erstellen, und habe mal wieder Grundsatzprobleme:

Problem1:
Vereinfacht sieht mein Code so aus:

Code: Alles auswählen

table = {"l1": [1,2,1], "l2": [1,1,3], "l3" : [1,1,1], "l4" : [1,2,3]}
#...
for entry1 in table:
    for entry2 in table:
        for entry3 in table:
            for entry4 in table:
                    setlist1 = compareSeq(table[entry1],table[entry2])
                    setlist2 = compareSeq(table[entry3],table[entry4])
                    if compareSets(setlist1,setlist2) == True:
                        print "(", entry1, entry2, "), (", entry3, entry4, ") are ambiguous"
Das funktioniert prinzipiell auch, liefert mir aber natürlich alles mehrfach, was ich gar nicht brauche:
( l4 l3 ), ( l2 l1 ) are ambiguous
( l4 l3 ), ( l1 l2 ) are ambiguous
( l2 l1 ), ( l4 l3 ) are ambiguous
( l2 l1 ), ( l3 l4 ) are ambiguous
( l3 l4 ), ( l2 l1 ) are ambiguous
( l3 l4 ), ( l1 l2 ) are ambiguous
( l1 l2 ), ( l4 l3 ) are ambiguous
( l1 l2 ), ( l3 l4 ) are ambiguous
Ich bräuchte eigentlich nur eine Zeile davon, weil die Reihenfolge der Paare und die Reihenfolge innerhalb der Paare nicht interessiert. Am liebsten hätte ich es auf die letzte Zeile reduziert (also alles in aufsteigender Reihenfolge).

Kann mir jemand nen Tipp geben, wie ich das hinkriege?

Problem 2:
Kann mir jemand sagen, was ich verwenden muss, um festzulegen dass entry1,2,3 und 4 alle verschieden sein sollen? Einfach nur

Code: Alles auswählen

entry1 != entry2 != entry3 != entry4
funktioniert nicht, der vergleicht nur die ersten beiden. Muss ich also wirklich das folgende nehmen?

Code: Alles auswählen

entry1 != entry2 and entry1 != entry3 and entry1 != entry4 and entry2 != entry3 and entry2 != entry4 and entry3 != entry4
Oder gibt es da auch was Einfacheres für?

Dankeschön!
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

http://docs.python.org/library/itertools.html

Für Problem 2 gibt es einen Trick:

Code: Alles auswählen

>>> l = [1,2,3,3]
>>> set(l)
set([1, 2, 3])
>>> len(set(l)) == len(l)
False
Bottle: Micro Web Framework + Development Blog
Lastalda
User
Beiträge: 10
Registriert: Dienstag 25. Mai 2010, 14:29

Danke! :D

Problem 2 wäre damit gelöst (ich wusste doch, das müsste über sets gehen! Mir war nur nicht klar, wie). :)

Problem 1...
ich bin mir noch nicht ganz sicher, auf welche der Funktionen es hinausläuft, scheine aber wiederum ein grundsätzliches Problem zu haben:
ich habe itertools importiert

Code: Alles auswählen

from itertools import *
habe also die Funktionen jetzt theorethisch zur Verfügung. Da ich mir bei einigen aus der Beschreibung nicht ganz sicher bin, was die tun, wollte ich sie testen, bekomme aber sehr seltsame Resultate, wie z.B. dieses hier:

Code: Alles auswählen

>>> chain("ABC","DEF")
<itertools.chain object at 0x02A97DF0>
Laut Dokumentation sollte das "A B C D E F" liefern... hä? *verwirrt*
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Lastalda hat geschrieben:

Code: Alles auswählen

>>> chain("ABC","DEF")
<itertools.chain object at 0x02A97DF0>
Laut Dokumentation sollte das "A B C D E F" liefern... hä? *verwirrt*
Nein, sollte es nicht. Die Dokumentation sagt "This module implements a number of iterator building blocks [...]".

Code: Alles auswählen

for i in chain("ABC", "DEF"):
    print i
l = list(chain("ABC", "DEF"))
print l
Lastalda
User
Beiträge: 10
Registriert: Dienstag 25. Mai 2010, 14:29

AH! Jetzt macht es mehr Sinn, danke!
Ich konnte mit der Beschreibung halt nichts anfangen, deswegen wollte ich es ja ausprobieren, und war dann verwirrt.

DANKE!
Lastalda
User
Beiträge: 10
Registriert: Dienstag 25. Mai 2010, 14:29

Ich raff's nicht, brauche wohl doch noch nen konkreteren Hinweis.

Ich vermute stark, dass ich die itertools.combinations()-Funktion benutzen sollte, um diese 4 for-loops zu vermeiden.
Also statt der 4 for-loops im 1. Post das hier:

Code: Alles auswählen

for i in combinations(table,2):
Oder war mit dem Link zu itertools was anderes gemeint?

Aber dann habe ich ja nur ein i, oder? Ich muss doch aber 4 verschiedene Elemente meines dictionaries miteinander vergleichen! Wie spreche ich die denn dann an?
*verwirrt*
BlackJack

@Lastalda: Schau Dir das eine `i` doch mal an. Welchen Typ das hat, was es enthält…
Lastalda
User
Beiträge: 10
Registriert: Dienstag 25. Mai 2010, 14:29

ah! *doofbin* okay, jetzt macht's mehr Sinn. Danke! :-)

Letztendlich hab ich's aber nun anders gelöst, indem ich nicht über n dictionary sondern über 2 getrennte Listen gegangen bin (die ich sowieso dahatte - das dictionary hab ich aus den Listen erst erzeugt).
Das funktionierende Ergebnis sieht dann so aus:

Code: Alles auswählen

def ambiguity(names,lists):
    n = len(names)
    for i in range(n):
        for j in range(i+1,n):
            for k in range(i+1,n):
                for l in range(k+1,n):
                    if j != l:
                        setlist1 = compareSeq(lists[i],lists[j])
                        setlist2 = compareSeq(lists[k],lists[l])
                        if compareSets(setlist1,setlist2) == True:
                            print "(", names[i], names[j], "), (", names[k], names[l], ") are ambiguous"
Trotzdem danke nochmal für die Hilfe. :-)
Antworten