5

ich eine bedingte Anweisung mit Python (2.7) eval() Funktion erzeugen wie so:Gibt es eine maximale Länge für eine Python-Bedingung (if) -Anweisung?

my_list = ['2 > 1','3 > 2','4 > 3'] 

if eval('(' + ') or ('.join(my_list) + ')'): 
    print 'yes' 
else: 
    print 'no' 

In meinem Fall wird die Liste von Code generiert, kommt my_list aus einer Parameterdatei, und die Liste ist verbunden mit ‚oder 'Anweisungen im Bedingungsausdruck. Der obige Code gibt 'ja' aus.

Es funktioniert gut für kleine Listen, aber bei einer bestimmten Anzahl von Zeichen in der eval()-Anweisung und ich bekomme einen String-Fehler.

finden einige Benutzer diese Threads, die auf einen Fehler hinweisen:

Aber ihr max eval() Größe ist viel größer als das, was ich gefunden . In meinem Fall finde ich zwischen 1744 und 1803 Zeichen, die Ausgabe beginnt. Ich habe versucht, diesen Code und es zwischen den beiden Aussagen

>>> eval("1.0*"*10000+"1.0") 
1.0 
>>> eval("1.0*"*100000+"1.0") 
# segfault here 

So hat zum Absturz bringen, die mich zu denken zurück bringen, dass es nicht eval(), aber tatsächlich einiger max auf der if Aussage.

Was ist eine andere Möglichkeit, die Regeln in der Liste, die keine langen Strings und die eval() - Funktion beinhalten, bedingt anzuwenden?

Interessanterweise habe ich my_list viel größer:

my_list = ['2 > 1']*1000000 

und der Code funktioniert gut ...

+0

Wenn die Liste der Bedingungen von Code generiert wird, warum werden sie nicht sofort bei der Erzeugung ausgewertet? Warum die Umwandlung in String überhaupt? –

+0

@OliverW. Die Bedingungen stammen aus einer Konfigurationsdatei. Da es sich um "oder" Aussagen handelt, sehe ich nicht genau, wie man eine nach der anderen bewertet. Ich denke, ich könnte ein boolesches Flag haben, das mit False beginnt und dann auf True gesetzt wird, wenn eine der if-Anweisungen als True ausgewertet wird. – philshem

Antwort

9

Vielleicht bin ich etwas fehlt, aber es scheint, dass:

any(map(eval, my_list)) 

Hat genau das, was Sie möchten.

from itertools import imap 

any(imap(eval, my_list)) # Python 2. 

Dies hat den schönen Effekt von nicht den Rest der Liste zu überprüfen das erste Element evals zu True (auch bekannt als „Kurzschluss“). Dies kann oder nicht sein, was Sie wollen.

Beispiel:

> any(map(eval, ['2 > 1','3 > 2','4 > 3'])) 
True 
+2

Hinweis: 'map' ist in Python 3 nur faul. Unter 2.7 kann stattdessen [' itertools.imap'] (http://docs.python.org/2/library/itertools.html#itertools.imap) verwendet werden um den gleichen Effekt zu erzielen. (Ich sage nur, weil OP Python 2.7 verwendet.) – Carsten

+0

Das macht genau das, was ich will, einschließlich der "Kurzschluss".Es gibt eine Menge Hass für eval(), aber ich sehe keinen anderen Weg. – philshem

+1

@philshem: Es gibt einen Hass für 'eval', aus gutem Grund, aber es existiert auch aus einem guten Grund. Wenn Ihr Ziel darin besteht, "etwas Python-Code auszuwerten", würde ich sagen, dass es das einfachste Tool für den Job ist. Denken Sie nur an die Auswirkungen auf die Sicherheit und ob dies ein Problem für Sie sein kann. – ereOn

Verwandte Themen