Wie Assignments in if-Statements ersetzen

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
webster
User
Beiträge: 4
Registriert: Mittwoch 13. Mai 2009, 20:49

Hallo,
aus C und Perl bin ich Ausdrücke der Art

Code: Alles auswählen

if (foo = function()) ...
gewöhnt. Konkret hätte ich das gerne für folgenden Anwendungsfall:

Code: Alles auswählen

if match = pattern1.match(line):
    block1
elif match = pattern2.match(line):
    block2
elif match = pattern3.match(line):
    block3
else:
    block4
Nach dem ganzen If-then-else soll das letzte match-Objekt erhalten bleiben, also darf ich nicht einfach weitermatchen, wenn ich schon was gefunden habe.
Als Anfänger sehe ich bisher nur zwei Möglichkeiten.
1) Eine hässliche Verschachtelung von ifs bis zur Tiefe 4.
2) Ich packe die Patterns in eine Liste und iteriere darüber. Das ist meiner Meinung nach aber Overkill für eine fixe Menge von Pattern. Das muss irgendwie einfacher gehen.

Danke schonmal.
BlackJack

Die Liste ist es. Wieso sollte das "Overkill" sein?
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Eine Schleife ist allgemein recht elegant:

Code: Alles auswählen

def block1(): pass
def block2(): pass
def block3(): pass
def default(): pass

matchers = [
	(re.compile("a"), block1),
	(re.compile("b"), block2),
	(re.compile("c"), block3),
]

for matcher, code in matchers:
	m = matcher.match(line)
	if m:
		code()
		break
else:
	default()
Bei genau 4 Varianten aber dann doch recht aufwendig. Wenn es machtbar ist, würde ich einfach alle 4 Pattern kombinieren und jeden zu einer Gruppe machen. Dann braucht man nur 1x match und kann dann über lastindex verzweigen:

Code: Alles auswählen

matcher = re.compile("(a)|(b)|(c)|(d)")

m = matcher.match(line)
if m:
  if m.lastindex == 1:
    block1
  elif m.lastindex == 2:
    block2
  elif m.lastindex == 3:
    block3
  else:
    default
Für Python 3 fällt mir noch folgendes ein:

Code: Alles auswählen

def match_line(line):
  m = None
  def match(pattern): nonlocal m; m = pattern.match(line); return m
  if match(p1):
    block1
  elif match(p2):
    block2
  elif match(p3):
    block3
  else:
    default
Stefan
webster
User
Beiträge: 4
Registriert: Mittwoch 13. Mai 2009, 20:49

Danke für die Antworten.
Ich habe jetzt folgendes Schema benutzt, das erscheint mir am einfachsten auch wenn es nicht schön ist:

Code: Alles auswählen

while True:
    match = pattern1.match(line)
    if match:
        block1
        break
    match = pattern2.match(line)
    if match:
        block2
        break
    match = pattern3.match(line)
    if match:
        block3
        break
    match = pattern4.match(line)
    if match:
        block4
        break
BlackJack

@webster: Da sollte dann aber wirklich besser eines der Muster passen. ;-)
webster
User
Beiträge: 4
Registriert: Mittwoch 13. Mai 2009, 20:49

Kleine Einrückungen, große Wirkung :)

Code: Alles auswählen

while True:
    match = pattern1.match(line)
    if match:
        block1
        break
    match = pattern2.match(line)
    if match:
        block2
        break
    match = pattern3.match(line)
    if match:
        block3
        break
    match = pattern4.match(line)
    if match:
        block4
    break
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Wer sich gern an Undokumentiertes wagt, kann sich auch `re.Scanner` anschauen :)
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Denk ich zu leicht, wenn ich an ein dict denke? =/ Bei mir löst ein dict oft so hässliche if-Verschachtelungen!
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

BlackVivi hat geschrieben:Denk ich zu leicht, wenn ich an ein dict denke? =/ Bei mir löst ein dict oft so hässliche if-Verschachtelungen!
Wie sollte ein dict in diesem Fall aussehen? Ich empfinde eine Schleife hier als die eleganteste Variante. Ist auch schöner erweiterbar.
Antworten