2009-07-07 8 views
7

Son birkaç gündür Python'u öğreniyorum ve bir postfix ifadesini değerlendirmek için bu kod parçasını yazdım.Python operatörleri

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() 

Bu engellemeden kaçınmanın bir yolu var mı? Dizin formunda matematiksel bir operatör alan ve buna karşılık gelen matematiksel operatörü veya bazı python deyimlerini çağrıştıran modül var mı?

cevap

16

operator modülünde standart aritmetik işleçleri uygulayan işlevler bulunur.

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

Sen çıkarma ve bölme için bu işlenen sağlamak için özen isteyecektir: Sonra ana döngü böyle bir şey bakabilirsiniz

OperatorFunctions = { 
    '+': operator.add, 
    '-': operator.sub, 
    '*': operator.mul, 
    '/': operator.div, 
    # etc 
} 

: gibi bu bilgiler sayesinde, bir eşleme ayarlayabilirsiniz Yığın doğru sırada atılır.

+1

Bu harika, Python'u seviyorum. +1 – Boldewyn

0

Sadece dize nesil ile birlikte eval kullanın:

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() 

DÜZENLEME: istisna işleme olmadan bile güzel versiyonunu yaptı.

+0

JS arkaplanından gelme: Python'da eval() JavaScript’te olduğu gibi kötü/yavaş mıdır? – Boldewyn

+0

Yavaşlıktan haberim yok. Çok dikkatli kullanılmadığında tehlikeli olabilir (yani güvensiz), ancak burada tüm girişler kontrol edildiğinden (tam sayılar veya sınırlı karakter kümesi) tamamen güvenlidir. – DzinX

+0

@Boldewyn: eval, her zaman eval() çağrılırken ayrıştırma ve derleme önemli bir yük olduğu için, Python'un dinamik özelliklerinden yararlanan eşdeğer çözümlerden genellikle daha yavaştır. Bir sözlük araması yapmak ve operatör modülü işlevlerini kullanmak (OperatorFunctions ["+"] (2, 2)), eval (eval ("2 + 2")) – Miles

0
[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) 
+0

@ over-zealous editörü: "despatcher" kabul "(dağıtıcı" için daha az yaygın) alternatif kabul edilir. Düzenlemenizi geri aldım. Lütfen yalnız bırakın. –

+0

@John: Bu "İngiliz İngilizcesi" vs "Amerikan İngilizcesi şeyler mi? – PTBNL

+0

@PTBNL: Bilmiyorum. FWIW: Google hit sayımları (milyonlar, 3 sig. Rakamlar): gönderme 8.25, 34.4 gönderi, despatcher 8.42, dağıtıcı 7.98. İlginç inversiyon. –