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:

Code: Alles auswählen

    return must_have in pair
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

Code: Alles auswählen

>>> any([5,num] in liste for num in xrange(10))
True
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 :oops:

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.

Code: Alles auswählen

>>> [3] == (3)
False
PS: Das ganze funktioniert übrigens auch verschachtelt:

Code: Alles auswählen

>>> [1,2,[ANY,[3]]] == [1,2,[9,[3]]]
True

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.

Code: Alles auswählen

>>> [3] == (3)
False
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.

Code: Alles auswählen

>>> x = "Test".__eq__(ANY)
>>> x
NotImplemented
Das veranlasst Python dazu, bei der anderen Seite Nachzuschauen:

Code: Alles auswählen

>>> ANY.__eq__("test")
True
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'>
>>>