You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 01:02:46