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

如何用Python实现表达式分步计算并处理此类分步输出结果?

Python实现表达式分步求值

实现思路

  • 预处理表达式:区分显示用表达式(保留原符号如^、–)和计算用表达式(转换为Python兼容的**、-)。
  • 按运算优先级逐步匹配并计算子表达式:优先级从高到低为「括号内幂运算 > 括号内乘除 > 括号内加减 > 全局幂运算 > 全局乘除 > 全局加减」。
  • 每计算一个子表达式,就替换显示用表达式中的对应部分,输出当前步骤,直到表达式简化为单一数值。

完整代码实现

import re

def step_by_step_eval(original_expr):
    # 初始化显示用表达式和计算用表达式
    display_expr = original_expr
    # 转换为Python可计算的表达式:^→**,全角减号→半角减号
    compute_expr = original_expr.replace('^', '**').replace('–', '-')
    
    # 定义匹配规则:(计算用正则, 计算替换式, 显示用正则),按优先级从高到低排列
    pattern_rules = [
        # 括号内的幂运算
        (r'\(([^\(\)]*?)(\d+)\^(\d+)([^\(\)]*?)\)', r'\(\1\2**\3\4\)', r'\(([^\(\)]*?)(\d+)\^(\d+)([^\(\)]*?)\)'),
        # 括号内的乘除运算
        (r'\(([^\(\)]*?)(\d+)\s*([*/])\s*(\d+)([^\(\)]*?)\)', r'\(\1\2\3\4\5\)', r'\(([^\(\)]*?)(\d+)\s*([*/])\s*(\d+)([^\(\)]*?)\)'),
        # 括号内的加减运算
        (r'\(([^\(\)]*?)(\d+)\s*([+-])\s*(\d+)([^\(\)]*?)\)', r'\(\1\2\3\4\5\)', r'\(([^\(\)]*?)(\d+)\s*([+-])\s*(\d+)([^\(\)]*?)\)'),
        # 全局幂运算
        (r'(\d+)\^(\d+)', r'\1**\2', r'(\d+)\^(\d+)'),
        # 全局乘除运算
        (r'(\d+)\s*([*/])\s*(\d+)', r'\1\2\3', r'(\d+)\s*([*/])\s*(\d+)'),
        # 全局加减运算
        (r'(\d+)\s*([+-])\s*(\d+)', r'\1\2\3', r'(\d+)\s*([+-])\s*(\d+)'),
    ]
    
    print(f'原始表达式: {original_expr}')
    
    while True:
        # 检查是否已简化为单一数值
        stripped_expr = display_expr.replace(' ', '')
        if re.fullmatch(r'-?\d+(\.\d+)?', stripped_expr):
            print(f'{" " * 21}= {display_expr}')
            break
        
        found_match = False
        for comp_pattern, comp_replace, disp_pattern in pattern_rules:
            # 在显示表达式中查找当前优先级的子式
            match = re.search(disp_pattern, display_expr)
            if match:
                # 提取子表达式并转换为可计算格式
                sub_comp_expr = re.sub(comp_pattern, comp_replace, match.group(0))
                # 计算子表达式结果
                result = eval(sub_comp_expr)
                # 整数结果转成int类型,避免显示为7.0
                result = int(result) if result.is_integer() else result
                result_str = str(result)
                
                # 替换显示表达式中的子式
                old_sub = match.group(0)
                display_expr = display_expr.replace(old_sub, result_str, 1)
                # 更新计算表达式
                compute_expr = compute_expr.replace(old_sub.replace('^', '**').replace('–', '-'), result_str, 1)
                
                # 输出当前步骤(对齐格式)
                print(f'{" " * 21}= {display_expr}')
                found_match = True
                break
        
        if not found_match:
            break

# 测试示例
input_expression = "(2 + 3 * 4) / 2 – (3^2 - 3)"
step_by_step_eval(input_expression)

代码说明

  1. 双表达式维护:
    • display_expr:始终保留用户输入的原始符号(如^、–),用于输出分步过程。
    • compute_expr:转换为Python支持的运算符号,用于调用eval()计算子式结果。
  2. 正则匹配优先级:
    按运算优先级顺序定义正则规则,确保每一步优先计算当前最高优先级的子表达式,符合数学运算逻辑。
  3. 结果格式化:
    将浮点整数(如7.0)转换为整数类型,保证输出格式与预期一致;通过固定空格数实现步骤行的对齐。

运行结果

原始表达式: (2 + 3 * 4) / 2 – (3^2 - 3)
                     = (2 + 12) / 2 – (3^2 - 3)
                     = 14 / 2 – (3^2 - 3)
                     = 7 – (3^2 - 3)
                     = 7 – (9 - 3)
                     = 7 – 6
                     = 1

内容的提问来源于stack exchange,提问作者Bảo Huy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 00:45:57