wildcards

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.
4bit
User
Beiträge: 113
Registriert: Dienstag 5. Mai 2009, 11:27

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.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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.
4bit
User
Beiträge: 113
Registriert: Dienstag 5. Mai 2009, 11:27

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.
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.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

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:
Zuletzt geändert von derdon am Montag 3. August 2009, 13:46, insgesamt 1-mal geändert.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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.
Benutzeravatar
HerrHagen
User
Beiträge: 430
Registriert: Freitag 6. Juni 2008, 19:07

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
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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. ;)
4bit
User
Beiträge: 113
Registriert: Dienstag 5. Mai 2009, 11:27

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.
4bit
User
Beiträge: 113
Registriert: Dienstag 5. Mai 2009, 11:27

danke herr hagen
4bit
User
Beiträge: 113
Registriert: Dienstag 5. Mai 2009, 11:27

@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.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

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".
4bit
User
Beiträge: 113
Registriert: Dienstag 5. Mai 2009, 11:27

ah. jetzt gehts.
Benutzeravatar
HerrHagen
User
Beiträge: 430
Registriert: Freitag 6. Juni 2008, 19:07

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
4bit
User
Beiträge: 113
Registriert: Dienstag 5. Mai 2009, 11:27

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.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

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 ;)
4bit
User
Beiträge: 113
Registriert: Dienstag 5. Mai 2009, 11:27

keine ahnung wen oder was dasich meint.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Ein Tupel würde so aussehen:MfG
HWK
Benutzeravatar
HerrHagen
User
Beiträge: 430
Registriert: Freitag 6. Juni 2008, 19:07

@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.
4bit
User
Beiträge: 113
Registriert: Dienstag 5. Mai 2009, 11:27

stimmt. wie seltsam.

Code: Alles auswählen

>>> type((3))
<type 'int'>
>>> type((3,))
<type 'tuple'>
>>> 
Antworten