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

如何用Python组合数字、运算符与函数生成所有合法表达式?

解决方案:生成数字、运算符与函数的组合表达式

要实现数字(不重复使用)、运算符(可重复)、函数的嵌套/组合表达式生成,核心是通过递归方式覆盖所有可能的表达式结构(纯数字、运算表达式、函数作用于表达式),同时保证数字不重复消耗。以下是可运行的实现代码:

import itertools
import math
import operator

# 运算符字符串到实际计算函数的映射
op_map = {
    '+': operator.add,
    '-': operator.sub
}

# 函数对象到名称字符串的映射(用于生成表达式文本)
func_name_map = {
    math.log: 'log',
    math.exp: 'exp'
}

def generate_expressions(numbers):
    expressions = []
    n = len(numbers)
    
    # 基础情况:单个数字的表达式
    if n == 1:
        num = numbers[0]
        # 纯数字表达式
        expressions.append((str(num), num))
        # 函数作用于单个数字的表达式(跳过无效计算,比如log(0))
        for fn in func_name_map:
            try:
                val = fn(num)
                expr_str = f"{func_name_map[fn]}({num})"
                expressions.append((expr_str, val))
            except ValueError:
                continue
        return expressions
    
    # 递归拆分数字为两个非空子集,生成组合表达式
    for split_idx in range(1, n):
        # 生成所有可能的数字拆分方式(保证数字不重复使用)
        for left_nums in itertools.combinations(numbers, split_idx):
            right_nums = tuple(set(numbers) - set(left_nums))
            # 递归生成左右子集的所有子表达式
            left_exprs = generate_expressions(left_nums)
            right_exprs = generate_expressions(right_nums)
            
            # 用运算符连接左右子表达式
            for (left_str, left_val), (right_str, right_val) in itertools.product(left_exprs, right_exprs):
                for op_str, op_func in op_map.items():
                    try:
                        calc_val = op_func(left_val, right_val)
                        # 给复杂子表达式加括号避免歧义
                        left_part = f"({left_str})" if len(left_nums) > 1 else left_str
                        right_part = f"({right_str})" if len(right_nums) > 1 else right_str
                        expr_str = f"{left_part} {op_str} {right_part}"
                        expressions.append((expr_str, calc_val))
                    except:
                        continue
    
    # 去重:避免不同生成路径产生相同表达式
    unique_exprs = []
    seen = set()
    for expr_str, val in expressions:
        if expr_str not in seen:
            seen.add(expr_str)
            unique_exprs.append((expr_str, val))
    return unique_exprs

# 测试运行
numbers = (9, 0, 1)
all_expressions = generate_expressions(numbers)

# 打印部分示例结果
print("部分生成的表达式:")
for expr, _ in all_expressions[:10]:
    print(expr)
print("...")

代码说明

  1. 映射表:op_map和func_name_map分别处理运算符的计算逻辑和函数的文本展示,方便生成可读的表达式字符串。
  2. 递归逻辑:
    • 单个数字时,生成纯数字和函数作用于数字的两种表达式。
    • 多个数字时,拆分数字为所有可能的非空子集,递归生成子表达式后用运算符连接,覆盖a op b、a op func(b)、func(a op b)等所有组合结构。
  3. 去重处理:避免因拆分顺序不同(如先拆a和b+c,再拆a+b和c)生成重复表达式。
  4. 异常处理:跳过无效计算(如log(0)),避免程序崩溃。

扩展方向

  • 新增运算符:在op_map中添加'*': operator.mul、'/': operator.truediv等即可。
  • 新增函数:在func_name_map中添加自定义函数或更多math模块函数(如math.sqrt)。
  • 过滤规则:可根据需求添加更多表达式过滤条件(如排除负数结果、限制表达式长度)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 20:21:11