самое простое решение, чтобы написать рекурсивную функцию, которая называет себя оценить внутренний выражения.
# helper function to parse strings where necessary
def intorfloat(number):
if not isinstance(number, str): # already parsed
return number
try:
return int(number)
except ValueError:
return float(number)
# evaluates a simple expression (no subexpressions)
def evaluate2(operation, operand1, operand2):
operand1, operand2 = intorfloat(operand1), intorfloat(operand2)
if operation == "*":
return operand1 * operand2
elif operation == "+":
return operand1 + operand2
elif operation == "/":
# keep the result an int if possible
result1 = operand1 // operand2
result2 = float(operand1)/operand2
return result1 if result1 == result2 else result2
elif operation == "-":
return operand1 - operand2
# recursively evaluate an expression with subexpressions
def evaluate(expression):
operation, operand1, operand2 = expression
if isinstance(operand1, list):
operand1 = evaluate(operand1)
if isinstance(operand1, list):
operand2 = evaluate(operand2)
return evaluate2(operation, operand1, operand2)
Итерационное решение также возможно; Преимущество состоит в том, что вы можете оценивать выражения любой глубины. В этой версии мы продолжаем спускаться в подсписки, пока не найдем лист: выражение, которое не имеет подвыражений. Затем мы оцениваем лист и заменяем его своим результатом и начинаем с самого начала. В конце концов выражение верхнего уровня не имеет подвыражений.
Этот алгоритм фактически модифицирует выражение, неоднократно упрощая его, пока его тривиально не оценить. (Рекурсивное решение не изменяет выражение.)
Если выражение глубокое, мы можем совершить много ненужного обхода, чтобы неоднократно находить листовые узлы. Мы могли бы создать стек, чтобы позволить нам отступать, вместо того, чтобы каждый раз начинать вверху, но мы могли бы просто использовать рекурсивное решение в этой точке.
# uses intorfloat() and evaluate2() functions previously shown
def evaluate(expression):
while isinstance(expression[1], list) or isinstance(expression[2], list):
current = expression
container = None
while True: # find a leaf node
operation, operand1, operand2 = current
if isinstance(operand1, list):
container, slot = current, 1
current = operand1
elif isinstance(operand2, list):
container, slot = current, 2
current = operand2
else:
break
if container:
container[slot] = evaluate2(*current)
return evaluate2(*expression)
print evaluate(['*', ['*', ['*', '5', '8'], '9'], '10']) # 3600
Что вы пытаетесь достичь? – ettanany
Это точно так же, как оценка дерева. Вам просто нужно определить на каждом шаге, если операнды являются деревьями и рекурсивно оценивают их.Если они не деревья (они листья), то вы пропустите оценку этой ветви и просто оцените выражение. – mgilson
@ettanany Я не был уверен, как это сделать, но, как я уже сказал в своем вопросе, думал о достижении этого, оценивая дерево. – jack