Seite 1 von 1
Logische Verknüpfungen als Variable
Verfasst: Mittwoch 8. Januar 2014, 06:52
von basstscho
Hallo zusammen,
ich bekomme einen Vergleichsoperator aus einer Variable und muss diesen in eine logische Verknüpfung einbauen - wie geht das?
Code: Alles auswählen
varE = 1
varA = 1
varC = 2
vo = "=="
if varE==varA and varC==varA:
pass
#Wie kann ich das mittels dem dynamischen logischen Operator in der Variable vo realisieren?
coStr = varE + vo + varA + " and " + varC + vo + varA
if doSomeMagic(coStr):
pass
Danke euch,
Johannes
Re: Logische Verknüpfungen als Variable
Verfasst: Mittwoch 8. Januar 2014, 07:48
von Sirius3
@basstscho: Zu jedem Operator gibt es auch eine entsprechende Funktion. Diese sind im Modul »operator« zusammengefasst:
Code: Alles auswählen
import operator
varA = 1
varC = 2
vo = operator.eq
if vo(varA,varC):
dosomething
Ich glaube aber nicht, dass das die optimale Lösung ist. Kannst Du Dein Problem noch näher beschreiben?
Re: Logische Verknüpfungen als Variable
Verfasst: Mittwoch 8. Januar 2014, 07:57
von anogayales
Hallo basstscho,
willkommen in Forum. Es gibt Wege wie du das in python realisieren kannst, sowie du es aber über Strings machst ist es sehr unüblich. Am besten sagst du uns was du eigentlich machen willst.
Falls du trotzdem das Ganze über Strings lösen willst musst du eine Abbildung konstruieren, die dir sagt welche String auf welchen Operator abbildet. So zum Beispiel:
Code: Alles auswählen
import operator
operator_mapping = {"==" : operator.eq,
"and" : operator.iand}
e = 1
a = 1
c = 2
vo = "=="
vi = "and"
result = operator_mapping[vi](operator_mapping[vo](c,a), operator_mapping[vo](e,a))
print result
Du siehst, dass du die Argumente nach dem Operator schreiben musst, du verlierst also die Infixnotation und nutzt stattdessen die Prefixnotation.
Den folgenden Abschnitt solltest du auf keinen Fall in produkivem Code verwenden! Er löst zwar das Problem, er dient lediglich zur Demonstration.
Code: Alles auswählen
result = eval("e {op1} a {op2} c {op1} a".format(op1="==", op2="and"))
print result
Grüße,
anogayales
Re: Logische Verknüpfungen als Variable
Verfasst: Mittwoch 8. Januar 2014, 08:01
von bwbg
Da Funktionen auch Objekte sind, kann man diese wunderbar in Datenstrukturen packen.
Hier bietet sich eine
lookup-table an, welche Zeichenketten auf Funktionen abbildet.
Zusammen mit dem operator-Modul sähe das zum Beispiel so aus:
Code: Alles auswählen
OPERATOR_LOOKUP = {
'==': operator.eq,
'+': operator.add,
# ...
}
def main():
a = 13
b = 29
print(OPERATOR_LOOKUP['=='](a, b))
print(OPERATOR_LOOKUP['+'](a, b))
if __name__ == '__main__':
main()
Edit: Zu langsam.
Wenn es sowas noch nicht gibt, sollte man eine PEP starten mit dem Ziel eval in evil umzubenennen.
Re: Logische Verknüpfungen als Variable
Verfasst: Mittwoch 8. Januar 2014, 08:56
von BlackJack
Und vor allem sollte man Leuten die man nicht einschätzen kann nicht gleich mit der Nase drauf stossen.

Re: Logische Verknüpfungen als Variable
Verfasst: Mittwoch 8. Januar 2014, 09:12
von anogayales
Lieber Leute davor explizit warnen, als dass sie selbst mit der Nase drauf stoßen und es gar in produktivem Code einsetzen, weil sie es nicht besser wissen.
Re: Logische Verknüpfungen als Variable
Verfasst: Mittwoch 8. Januar 2014, 09:27
von Sirius3
@anogayales: wie eine Warnung liest sich Dein Beitrag dazu aber nicht gerade.
Re: Logische Verknüpfungen als Variable
Verfasst: Mittwoch 8. Januar 2014, 10:02
von anogayales
Danke Sirius3, ich haben es nun deutlicher formuliert.
Re: Logische Verknüpfungen als Variable
Verfasst: Donnerstag 9. Januar 2014, 06:47
von basstscho
Hallo zusammen,
vielen Dank für eure zahlreichen Antworten. Nochmals kurz zum Hintergrund:
Ich habe in einer csv-Tabelle mehrere Spalten die für eine Variable stehen. In den Zeilen stehen dann jeweils Werte. Es soll nun überprüft werden welche Zeilen auf Grund des aktuellen Variablenstatus erfüllt sind und welche nicht. Zusätzlich kommt hinzu, dass in den Zellen zum Wert vorangestellt die Vergleichsoperatoren >, <, >=, <= stehen können.
Ich habe es nun mit einer Schleife gelöst die über sämtliche Werte in einer Zeile läuft und eine Unterfunktion aufruft die mit einem String-Vergleich überprüft welcher Operator zum Einsatz kommen soll (zunächst die mit zwei Zeichen, dann die mit einem und bei keinem (entsprich das ==)) und dann mittels der entsprechenden Operator-Funktion vergleicht. Bekomme ich einmal im Durchlauf ein False zurück, ist die ganze Zeile nicht erfüllt.
Somit kann ich vorab noch überprüfen ob die Eingabe Sinn macht und gehe nicht direkt aus der Benutzereingabe in den Vergleich.
Habt ihr noch ne bessere Idee?
Beste Grüße,
Johannes
Re: Logische Verknüpfungen als Variable
Verfasst: Donnerstag 9. Januar 2014, 08:42
von Sirius3
@basstscho: sehe ich das richtig, die Datei sieht so aus?
Wer denkt sich denn sowas aus?
Code: Alles auswählen
import csv
import operator
from itertools import imap
OPERATORS = [
('<=', operator.le),
('>=', operator.ge),
('<>', operator.ne),
('!=', operator.ne),
('==', operator.eq),
('<', operator.lt),
('>', operator.gt),
('=', operator.eq),
('', operator.eq),
]
def split_operator(value):
if isinstance(value, basestring):
for symbol, operation in OPERATORS:
if value.startswith(symbol):
return float(value[len(symbol):]), operation
raise RuntimeError('Internal Error')
else:
return float(value), operator.eq
def validate(values):
values = iter(values)
first = float(next(values))
return all(operation(first, value)
for value, operation in imap(split_operator, values))
def main():
with open('datei.csv') as data:
for row in csv.reader(data):
print validate(row)
if __name__ == '__main__':
main()