如何用Python 3.11计算含数字与算术运算符的字符串数组
解决方案
方法1:直接用eval()快速计算(适合可信输入)
把数组元素拼接成完整的表达式字符串,用eval()执行即可,它能自动处理整数、浮点数以及带括号的复杂运算:
# 示例1 arr = ['2', '*', '2'] expr = ''.join(arr) result = eval(expr) print(result) # 输出:4 # 示例2 arr = ['(', '1', '6', '*', '0', ')', '+', '(', '1', '6', '*', '1', ')', '+', '5'] expr = ''.join(arr) result = eval(expr) print(result) # 输出:21 # 浮点数测试 arr = ['1', '.', '1', '0', '+', '2', '.', '4', '2'] expr = ''.join(arr) print(eval(expr)) # 输出:3.52
注意:eval()会执行任意Python代码,如果数组内容来自不可信来源(比如用户输入),绝对不能用这个方法,存在严重安全风险。
方法2:用ast模块安全求值(限制为表达式)
用ast.parse()先将字符串解析为表达式语法树,再求值,比直接用eval()更安全,因为它只允许表达式,不支持执行语句类代码:
import ast def safe_evaluate(expr): # 解析为表达式语法树 tree = ast.parse(expr, mode='eval') # 编译并求值 return eval(compile(tree, filename='', mode='eval')) # 测试示例 arr = ['(', '1', '.', '6', '*', '0', ')', '+', '5', '.', '2'] expr = ''.join(arr) print(safe_evaluate(expr)) # 输出:5.2
方法3:手动解析表达式(完全可控,无安全风险)
如果需要完全控制运算逻辑,或者处理不可信输入,可以手动合并数字片段、转换为数值类型,再通过栈实现表达式求值(基于逆波兰表达式):
步骤1:合并数字片段(处理整数和浮点数)
def merge_number_tokens(arr): merged_tokens = [] current_num = [] for token in arr: # 判断是否为数字或小数点 if token in '0123456789.': current_num.append(token) else: # 把当前累积的数字转为float加入列表 if current_num: merged_tokens.append(float(''.join(current_num))) current_num = [] merged_tokens.append(token) # 处理最后一个数字 if current_num: merged_tokens.append(float(''.join(current_num))) return merged_tokens
步骤2:中缀表达式转后缀表达式(逆波兰式)
def infix_to_postfix(tokens): # 运算符优先级:乘除高于加减 precedence = {'+': 1, '-': 1, '*': 2, '/': 2, '(': 0} output = [] operator_stack = [] for token in tokens: if isinstance(token, float): # 数字直接加入输出列表 output.append(token) elif token == '(': # 左括号入栈 operator_stack.append(token) elif token == ')': # 弹出栈内运算符直到遇到左括号 while operator_stack and operator_stack[-1] != '(': output.append(operator_stack.pop()) operator_stack.pop() # 丢弃左括号 else: # 弹出优先级大于等于当前运算符的栈顶元素 while operator_stack and precedence[operator_stack[-1]] >= precedence[token]: output.append(operator_stack.pop()) operator_stack.append(token) # 弹出剩余运算符 while operator_stack: output.append(operator_stack.pop()) return output
步骤3:计算后缀表达式
def evaluate_postfix(postfix_tokens): stack = [] for token in postfix_tokens: if isinstance(token, float): stack.append(token) else: # 弹出两个操作数,注意顺序 b = stack.pop() a = stack.pop() if token == '+': stack.append(a + b) elif token == '-': stack.append(a - b) elif token == '*': stack.append(a * b) elif token == '/': stack.append(a / b) return stack[0]
完整测试
# 测试复杂表达式 arr = ['(', '1', '6', '*', '0', ')', '+', '(', '1', '6', '*', '1', ')', '+', '5'] merged = merge_number_tokens(arr) postfix = infix_to_postfix(merged) result = evaluate_postfix(postfix) print(result) # 输出:21.0 # 测试浮点数 arr = ['4', '.', '1', '7', '*', '1', '.', '1', '0'] merged = merge_number_tokens(arr) postfix = infix_to_postfix(merged) print(evaluate_postfix(postfix)) # 输出:4.587
内容的提问来源于stack exchange,提问作者João Amgarten
相关产品推荐
相关产品推荐

