如何在Python中不使用eval计算含+-*/的字符串表达式
eval() (Prioritizing Multiplication/Division) Hey there, I see you're stuck on calculating the expression 1+2*3*4+5-1+6/2 (which should equal 32) without relying on eval(), and your initial attempt to prioritize multiplication isn't working out. Let's walk through a solid, step-by-step solution that fixes this.
First, let's outline the core approach we need:
- Split the input string into a list of numbers and operators (so we can manipulate each part easily)
- First process all multiplication and division operations left-to-right
- Then handle the remaining addition and subtraction to get the final total
Full Working Code
def tokenize_expression(expr): tokens = [] current_num = '' for char in expr: if char in '+-*/': if current_num: tokens.append(int(current_num)) current_num = '' tokens.append(char) else: current_num += char # Add the last number in the expression if current_num: tokens.append(int(current_num)) return tokens def compute(expr): tokens = tokenize_expression(expr) # First handle multiplication and division operations i = 1 while i < len(tokens): op = tokens[i] if op == '*' or op == '/': left_val = tokens[i-1] right_val = tokens[i+1] # Calculate the result of the operation if op == '*': result = left_val * right_val else: # Using integer division here to match your example's 6/2=3 result = left_val // right_val # Replace the left number, operator, right number with the result tokens = tokens[:i-1] + [result] + tokens[i+2:] # Don't increment index - we just shortened the list continue i += 1 # Now handle addition and subtraction total = tokens[0] i = 1 while i < len(tokens): op = tokens[i] num = tokens[i+1] if op == '+': total += num else: total -= num i += 2 return total # Test with your target expression print(compute('1+2*3*4+5-1+6/2')) # Outputs 32
Let's Break This Down
Tokenization: The
tokenize_expressionfunction turns your input string into a structured list of integers and operators. For your example, it converts1+2*3*4+5-1+6/2into[1, '+', 2, '*', 3, '*', 4, '+', 5, '-', 1, '+', 6, '/', 2]. This makes it easy to iterate through and process operations in order.Processing Multiplication/Division: We loop through the tokens, and whenever we hit a
*or/, we calculate the result, then replace the three elements (left number, operator, right number) with that result. We don't increment the index after this because the list has gotten shorter, and we need to check the new element at the same position (this handles chained operations like2*3*4correctly).Processing Addition/Subtraction: Once all multiply/divide operations are done, the tokens list only has numbers and
+/-operators. We start with the first number as our total, then iterate through each operator to update the final result.
Fixing Your Original Issues
- You mentioned using
Leninstead oflen– in Python, the correct built-in function is lowercaselen(), which the code above uses properly. - The main problem with your initial attempt was likely not modifying the list correctly for chained operations. Just adding individual numbers won't account for sequences like
2*3*4, which needs to be calculated step-by-step as(2*3)*4 = 24.
内容的提问来源于stack exchange,提问作者user9729087

