2009-07-07 5 views
7

지난 며칠 동안 파이썬을 배우기 때문에이 코드를 작성하여 후위 표현식을 평가했습니다.파이썬 운영자

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

거대한 블록을 피할 수있는 방법이 있습니까? 마찬가지로, 문자열 형식의 수학 연산자를 사용하고 해당 수학 연산자 또는 이것을 간단하게 만드는 일부 파이썬 관용구를 호출하는 모듈이 있습니까?

답변

16

operator 모듈에는 표준 산술 연산자를 구현하는 함수가 있습니다.

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

당신은 뺄셈과 나눗셈 해당 피연산자를 확인하는데주의를 기울여야 할 것입니다 : 그런 다음 메인 루프는 다음과 같이 보일 수

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

:처럼 그것으로, 당신은 매핑을 설정할 수 있습니다 스택에서 올바른 순서로 팝프됩니다.

+1

멋지다. 나는 파이썬을 좋아한다. +1 – Boldewyn

0

그냥 캐릭터 생성과 함께 eval를 사용

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

편집가 : 예외 처리하지 않고 심지어 더 좋은 버전을했다.

+0

JS 백그라운드에서 나온 것 : Python의 eval()이 JavaScript처럼 느리거나 느린가요? – Boldewyn

+0

나는 천천히 몰라요. 아주 신중하게 사용하지 않으면 위험 할 수 있습니다 (예 : 안전하지 않음). 그러나 여기에서는 모든 입력을 검사 할 때 완벽하게 안전합니다 (정수 또는 제한된 문자 집합). – DzinX

+0

@Boldewyn : eval은 파이썬의 동적 기능을 이용하는 동급 솔루션보다 일반적으로 느립니다. eval()이 호출 될 때마다 구문 분석 및 컴파일에 상당한 오버 헤드가 있기 때문입니다. 사전 검색을 수행하고 연산자 모듈 함수 (OperatorFunctions [ "+"] (2, 2))를 사용하면 eval ("2 + 2")을 사용하는 것보다 약 60 배 빠릅니다. – 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"는 "dispatcher"의 대안으로 받아 들여지고 있습니다. 나는 당신의 편집을 다시 굴 렸습니다. 혼자 남겨주세요. –

+0

@ 존 : 이것은 "영국 영어"대 "미국 영어"중 하나입니까? – PTBNL

+0

@PTBNL : 잘 모르겠습니다 .FWIW : Google 조회수 (수백만, 3 자릿수) : 발송 8.25, 발송 34.6, despatcher 8.42, dispatcher 7.98 흥미로운 반전. –