Seite 1 von 2
wildcards
Verfasst: Montag 3. August 2009, 13:18
von 4bit
Hallo!
ich habe eine Liste von Integer-Pärchen (sollen als Kanten in einem gerichteten Graphen interpretiert werden) und ich möchte jetzt prüfen, ob die In- und Outdegrees jedes Knotens mindestens gleich 1 sind (alle Knoten sollen in diesem Sinne "relevant" sein).
Sehr einfach wäre daß zu lösen, wenn ich abfragen könnte, ob [2,*] und [*,2] in der Liste enthalten sind. Gibts bei Python so ein * Symbol?
grüße,
4bit.
Verfasst: Montag 3. August 2009, 13:27
von snafu
Code: Alles auswählen
In [5]: def check_pair(pair, must_have=2):
...: return pair[0] == must_have or pair[1] == must_have
...:
In [6]: check_pair([2, 9])
Out[6]: True
In [7]: check_pair([1, 9])
Out[7]: False
In [8]: check_pair([1, 2])
Out[8]: True
In [9]: check_pair([2, 2])
Out[9]: True
Für `must_have` lässt sich dann halt auch eine andere Zahl einsetzen, da du mal von 2 und mal von 1 sprichst, wenn ich dich richtig verstanden habe. Übrigens sollte man hier IMHO Tuple statt Listen verwenden.
Verfasst: Montag 3. August 2009, 13:36
von 4bit
das ist nicht was ich meine.
Code: Alles auswählen
liste = [[5,4],[6,8],[9,0]]
In [5]: [5,4] in liste
Out [6]: True
Mit dieser Zeile frage ich ab ob [5,4] in der Liste enthalten ist. Gibt es ein wildcard symbol, sodaß ich abfragen kann ob zum Beispiel [5,*] in der liste enthalten ist?
ich möchte entscheiden ob für alle Zahlen zwischen 1 und n in der liste Pärchen enthalten sind, die jeweils mit dieser Zahl beginnen und enden.
Wegen den Tupeln: theoretisch ja, aber mir ist es noch nie passiert, daß die Reihenfolge der Elemente einer Liste sich plötzlich ändert. Für meine Zwecke ist eine Liste gut genug.
Verfasst: Montag 3. August 2009, 13:41
von BlackJack
@4bit: Du musst die `check_pair()`-Funktion eben auf alle Elemente anwenden. Zum Beispiel in Verbindung mit `any()`. ``any(imap(check_pair, liste))`` mit `itertools.imap()`.
`check_pair` müsste man so etwas einfacher ausdrücken können:
Wobei man da natürlich die Funktion auch weglassen könnte und nur ``any(2 in p for p in liste)`` schreiben kann.
Verfasst: Montag 3. August 2009, 13:45
von derdon
Den Wert von xrange musst du evtl. anpassen, weil ich mir nicht sicher bin, wie hoch der Wert laut dir sein darf (sind das immer nur einstellige Zahlen oder können sie beliebig groß werden?).
Edit: BlackJack war schneller und hats schöner

Verfasst: Montag 3. August 2009, 13:46
von snafu
Klappt doch immer noch:
Code: Alles auswählen
In [13]: for elem in [(5, 4), (6, 8), (9, 0)]:
....: print '%s -> %s' % (elem, check_pair(elem, 5))
....:
....:
(5, 4) -> True
(6, 8) -> False
(9, 0) -> False
Das mit dem Tuple meinte ich eher vom deskriptiven Ansatz her. Ich bin halt der Meinung, dass ein Pärchen damit besser als mit einer Liste beschrieben wird.
Verfasst: Montag 3. August 2009, 13:49
von HerrHagen
Nein, es gibt kein solches Symbol. Aber du kannst dir leicht eins definieren:
Code: Alles auswählen
>>> class MatchAnything:
def __eq__(self, other):
return True
>>> ANY = MatchAnything()
>>> (3, 4) == (3, ANY)
True
>>> (3, 4) == (4, ANY)
False
>>> (4, ANY) in [(4,5), (6,4)]
True
MFG HerrHagen
Verfasst: Montag 3. August 2009, 13:51
von snafu
BlackJack hat geschrieben:Wobei man da natürlich die Funktion auch weglassen könnte und nur ``any(2 in p for p in liste)`` schreiben kann.
Python kann so einfach sein.

Verfasst: Montag 3. August 2009, 13:51
von 4bit
ok danke. gibt wohl kein wildcardsymbol. wie man check_pair verwendet ist mir schon klar, aber wenn es syntax gibt, die die gleiche aufgabe ohne eine funktion zu definieren gibt, warum nicht? any ist ja schon nah dran.
Verfasst: Montag 3. August 2009, 13:53
von 4bit
danke herr hagen
Verfasst: Montag 3. August 2009, 15:14
von 4bit
@HerrHagen:
Ich habe gerade versucht deine Lösung für die wildcards zu nutzen und festgestellt, daß es bei mir nicht funktioniert, weil ich listen anstatt tupel vergleichen will. funktioniert __eq__ bei tupeln anders, als bei listen?
grüße,
4bit.
Verfasst: Montag 3. August 2009, 15:25
von cofi
Du hast das Snippet nicht verstanden, deshalb gehts in die Hose.
Das Objekt gibt bei _jedem_ Vergleich auf Gleichheit ``True`` zurueck.
"Nicht funktioniert" ist uebrigens "Nicht hilfreich".
Verfasst: Montag 3. August 2009, 15:35
von 4bit
ah. jetzt gehts.
Verfasst: Montag 3. August 2009, 17:27
von HerrHagen
Ich nehm mal an du hast tuple mit listen verglichen. Deren Vergleich endet jedoch immer negativ (ein tuple ist nunmal keine Liste). Unabhängig ob ein ANY enthalten ist.
PS: Das ganze funktioniert übrigens auch verschachtelt:
Verfasst: Donnerstag 6. August 2009, 13:54
von 4bit
was mit noch nicht klar ist: wenn ich zwei objekte vergleiche, hat jedes eine eigene vergleichsmethode, die gegenteilige antworten liefern können. zum beispiel ANY == "einstring" gibt true zurück. die _eq_ vom string müßte aber eigentlich false zurückgeben, da ANY ja kein string ist.
besteht dieser konflikt wirklich? und wenn ja, gilt hier das prinzip: was der programmierer festlegt ist wichtiger als interne methoden?
grüße,
4bit.
Verfasst: Donnerstag 6. August 2009, 14:22
von DasIch
HerrHagen hat geschrieben:Ich nehm mal an du hast tuple mit listen verglichen. Deren Vergleich endet jedoch immer negativ (ein tuple ist nunmal keine Liste). Unabhängig ob ein ANY enthalten ist.
Die Aussage mag stimmen trotzdem vergleichst du hier eine Liste mit einer Zahl

Verfasst: Donnerstag 6. August 2009, 14:25
von 4bit
keine ahnung wen oder was dasich meint.
Verfasst: Donnerstag 6. August 2009, 14:28
von HWK
Ein Tupel würde so aussehen:
MfG
HWK
Verfasst: Donnerstag 6. August 2009, 14:34
von HerrHagen
@4bit: Die String Methode für den Gleichheitstest gibt nicht False sondern NotImplemented zurück.
Das veranlasst Python dazu, bei der anderen Seite Nachzuschauen:
Dort kommt ein verwertbares Ergebnis raus, was Python dazu veranlasst dieses zurückzugeben.
Verfasst: Donnerstag 6. August 2009, 14:34
von 4bit
stimmt. wie seltsam.
Code: Alles auswählen
>>> type((3))
<type 'int'>
>>> type((3,))
<type 'tuple'>
>>>