2009-07-07 39 views
7

Tôi đang học Python trong vài ngày qua và tôi đã viết đoạn mã này để đánh giá biểu thức postfix.Toán tử Python

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

Có cách nào tôi có thể tránh được điều đó nếu chặn khác không? Như trong, là có mô-đun mà có một toán tử toán học ở dạng chuỗi và gọi toán tử tương ứng toán học hoặc một số thành ngữ python mà làm cho điều này đơn giản?

Trả lời

16

Mô-đun operator có các chức năng triển khai toán tử số học chuẩn. Với điều đó, bạn có thể thiết lập một ánh xạ như:

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

Sau đó, vòng lặp chính của bạn có thể trông giống như thế này:

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

Bạn sẽ muốn chăm sóc để đảm bảo rằng các toán hạng để trừ và phân chia được bật ra khỏi ngăn xếp theo đúng thứ tự.

+1

Thật tuyệt, tôi thích Python. +1 – Boldewyn

0

Chỉ cần sử dụng eval cùng với thế hệ chuỗi:

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

EDIT: thực hiện một phiên bản thậm chí đẹp hơn mà không xử lý ngoại lệ.

+0

Đến từ một nền JS: Là eval() trong Python là xấu/chậm như trong JavaScript? – Boldewyn

+0

Tôi không biết về sự chậm chạp. Nó có thể nguy hiểm (tức là không an toàn) nếu không được sử dụng rất cẩn thận, nhưng ở đây nó hoàn toàn an toàn khi tất cả đầu vào được kiểm tra (số nguyên hoặc một bộ ký tự giới hạn). – DzinX

+0

@Boldewyn: eval thường chậm hơn so với các giải pháp tương đương tận dụng các tính năng động của Python, vì có chi phí đáng kể trong phân tích cú pháp và biên dịch mỗi khi eval() được gọi. Thực hiện tra cứu từ điển và sử dụng các chức năng của mô-đun vận hành (OperatorFunctions ["+"] (2, 2)) nhanh hơn khoảng 60 lần so với sử dụng 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 editor: "despatcher" là một chấp nhận (mặc dù bị cáo buộc ít phổ biến hơn) thay thế cho "dispatcher". Tôi đã cuộn lại bản chỉnh sửa của bạn. Hãy để nó một mình. –

+0

@John: Đây có phải là một trong những "tiếng Anh Anh" và "những thứ tiếng Anh của Mỹ không? – PTBNL

+0

@PTBNL: Tôi không biết. FWIW: Số lần truy cập của Google (hàng triệu, 3 sig. Chữ số): gửi đi 8.25, công văn 34.6, despatcher 8.42, điều phối viên 7.98. –

Các vấn đề liên quan