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

Python自定义数学求值器开发需求及问题修复

私人Python数学求值器优化方案

针对需求,以下是优化后的完整实现,解决了多列表运算、多函数组合及隐式乘法的问题,同时满足所有核心功能要求:

完整代码实现

import re
import math

class MathList(list):
    def __init__(self, iterable=()):
        super().__init__(iterable)
    
    def _op(self, other, op):
        """通用运算处理函数,实现笛卡尔积运算与标量运算"""
        result = []
        # 处理两个列表的笛卡尔积运算
        if isinstance(other, MathList):
            for x in self:
                for y in other:
                    result.append(op(x, y))
        # 处理列表与标量的运算
        else:
            for x in self:
                result.append(op(x, other))
        # 去重并保持元素首次出现的顺序
        return MathList(dict.fromkeys(result).keys())
    
    # 重载基础运算符
    def __add__(self, other):
        return self._op(other, lambda a, b: a + b)
    
    def __sub__(self, other):
        return self._op(other, lambda a, b: a - b)
    
    def __mul__(self, other):
        return self._op(other, lambda a, b: a * b)
    
    def __truediv__(self, other):
        return self._op(other, lambda a, b: a / b)
    
    # 重载反向运算符,处理标量在前、列表在后的情况(如3 - [1,2])
    def __radd__(self, other):
        return self._op(other, lambda a, b: b + a)
    
    def __rsub__(self, other):
        return self._op(other, lambda a, b: b - a)
    
    def __rmul__(self, other):
        return self._op(other, lambda a, b: b * a)
    
    def __rtruediv__(self, other):
        return self._op(other, lambda a, b: b / a)

def preprocess_expression(expr):
    """预处理表达式,自动插入隐式乘法的乘号"""
    # 正则规则覆盖所有隐式乘法场景
    patterns = [
        # 数字后接括号/列表:如2(3) → 2*(3);2[1,2] →2*[1,2]
        r'(\d+(?:\.\d+)?)\s*([\(\[])',
        # 括号/列表后接数字/括号/列表:如(3)2→(3)*2;[1,2](3)→[1,2]*(3)
        r'([\)\]])\s*(\d+(?:\.\d+)?|[\(\[])',
        # 括号与列表互相嵌套:如([1,2])→([1,2]);[(3)]→[(3)]
        r'(\()\s*(\[)',
        r'(\[)\s*(\()'
    ]
    for pattern in patterns:
        expr = re.sub(pattern, r'\1*\2', expr)
    return expr

def custom_random(start, end, step=0.1):
    """自定义random函数,支持浮点数范围的序列生成"""
    result = []
    current = start
    # 用round避免浮点数精度误差导致的循环异常
    while round(current, 10) < round(end, 10):
        result.append(current)
        current += step
        current = round(current, 10)
    return MathList(result)

def evaluate_math(expr):
    """主求值函数,处理所有输入表达式"""
    # 预处理隐式乘法
    processed_expr = preprocess_expression(expr)
    # 替换普通列表为自定义MathList,实现重载运算
    processed_expr = re.sub(r'\[(.*?)\]', r'MathList([\1])', processed_expr)
    
    # 构建安全的命名空间(仅包含允许的函数与常量)
    namespace = {
        '__builtins__': None,
        'random': custom_random,
        'MathList': MathList
    }
    # 导入math模块的所有公开函数与常量
    for attr in dir(math):
        if not attr.startswith('_'):
            namespace[attr] = getattr(math, attr)
    
    try:
        result = eval(processed_expr, namespace)
        # 标量结果转换为单元素列表
        if not isinstance(result, MathList):
            result = MathList([result])
        return list(result)
    except Exception as e:
        raise ValueError(f"表达式解析错误: {expr}") from e

# 测试用例
if __name__ == "__main__":
    print(evaluate_math("3"))                  # 输出: [3]
    print(evaluate_math("round(419.9)"))       # 输出: [420]
    print(evaluate_math("[2,1]-[0,1]"))        # 输出: [2, 1, 0]
    print(evaluate_math("random(0.1,0.5)"))    # 输出: [0.1, 0.2, 0.3, 0.4]
    print(evaluate_math("log(e)"))             # 输出: [1.0]
    print(evaluate_math("2(3)"))               # 输出: [6]
    print(evaluate_math("(2+3)(4)"))           # 输出: [20]
    print(evaluate_math("2[1,3]"))             # 输出: [2, 6]
    print(evaluate_math("[1,2]*3"))            # 输出: [3, 6]
    print(evaluate_math("random(1,5,2)"))      # 输出: [1, 3]

核心功能实现说明

1. 隐式乘法支持

通过preprocess_expression函数使用正则表达式自动识别并插入乘号,覆盖所有常见隐式场景:

  • 数字后接括号/列表(如2(3)→2*(3))
  • 括号/列表后接数字/括号/列表(如[1,2]3→[1,2]*3)
  • 括号与列表互相嵌套(如([1,2])→([1,2]))

2. 列表递归运算

通过自定义MathList类重载运算符,实现:

  • 两个列表间的笛卡尔积运算(如[2,1]-[0,1]生成所有元素对的减法结果)
  • 列表与标量的逐元素运算(如[1,2]*3生成[3,6])
  • 自动去重并保持元素首次出现的顺序

3. 自定义random函数

实现支持浮点数范围的序列生成,通过round处理浮点数精度问题,避免循环异常,默认步长为0.1,支持自定义步长。

4. Math模块集成

将math模块的所有公开函数与常量导入命名空间,支持如log(e)、sin(pi/2)等表达式求值。

5. 基础求值兼容

所有标量表达式求值后自动转换为单元素列表,保持输出格式统一;同时兼容Python内置函数(如round)的正常使用。

内容的提问来源于stack exchange,提问作者Machinexa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 19:20:57