7
votes

Opérateurs de python

J'apprends Python ces derniers jours et j'ai écrit ce morceau de code pour évaluer une expression postfix.

postfix_expression = "34*34*+"

stack = []

for char in postfix_expression :
    try :
        char = int(char);
        stack.append(char);
    except ValueError:
        if char == '+' :
            stack.append(stack.pop() + stack.pop())
        elif char == '-' :
            stack.append(stack.pop() - stack.pop())
        elif char == '*' :
            stack.append(stack.pop() * stack.pop())
        elif char == '/' :
            stack.append(stack.pop() / stack.pop())

print stack.pop()


0 commentaires

3 Réponses :


16
votes

le opérateur code> module a des fonctions qui implémentent la norme opérateurs arithmétiques. Avec cela, vous pouvez configurer un mappage comme: xxx pré>

puis votre boucle principale peut ressembler à ceci: p>

for char in postfix_expression:
    if char in OperatorFunctions:
        stack.append(OperatorFunctions[char](stack.pop(), stack.pop()))
    else:
        stack.append(char)


1 commentaires

FYI - opérateur Les fonctions semblent être incroyablement lentes. % TimeIt 1 + 3 - Donne 12.5ns tandis que % Timeit opérateur.Ajouter (1, 3) donne 101n (9 fois plus lent: o)



0
votes

Il suffit d'utiliser eval ainsi que génération de chaînes:

postfix_expression = "34*34*+"
stack = []
for char in postfix_expression:
    if char in '+-*/':
        expression = '%d%s%d' % (stack.pop(), char, stack.pop())
        stack.append(eval(expression))
    else:
        stack.append(int(char))
print stack.pop()


4 commentaires

Venant d'un contexte JS: Eval () en Python est-il aussi mauvais / lent que dans JavaScript?


Je ne sais pas sur la lenteur. Cela peut être dangereux (c'est-à-dire dangereux) s'il n'est pas très soigneusement utilisé, mais ici, il est parfaitement sûr car toute entrée est vérifiée (entiers ou un jeu de caractères limité).


@Boldewyn: Eval est généralement plus lent que des solutions équivalentes qui tirent parti des caractéristiques dynamiques de Python, car il y a une augmentation substantielle dans l'analyse et la compilation de chaque fois que Eval () est appelée. Faire une recherche de dictionnaire et utiliser les fonctions du module d'opérateur (fonctionnalités de commande ["+"] (2, 2)) est d'environ 60 fois plus rapide que d'utiliser Eval (Eval ("2 + 2"))


Cool, merci pour les réponses! Donc, c'est une sorte de la même chose que chez JS ... (concernant la sécurité et la rapidité)



0
votes
[untested]
from operator import add, sub, mul, div
# read the docs; this is a tiny part of the operator module

despatcher = {
    '+': add,
    '-': sub,
    # etc
    }

opfunc = despatcher[op_char]
operand2 = stack.pop()
# your - and / are bassackwards
stack[-1] = opfunc(stack[-1], operand2)

3 commentaires

@ Editeur trop zélé: "Dépatter" est une alternative acceptée (bien que prétendément moins commune) au "répartiteur". J'ai roulé votre édition de retour. S'il vous plaît laissez-le seul.


@John: Est-ce l'un de ces "anglophones" anglophones "vs" American Anglais?


@Ptbnl: Je ne sais pas. FWIW: Google Hit Counts (Millions, 3 SIG. Chiffres): Expédition 8.25, Dispatch 34,6, Dépatter 8.42, Dispatcher 7.98. Inversion intéressante.