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

使用Sympy to_nnf转换布尔函数时调用eval()触发MemoryError问题

解决Sympy处理超大布尔函数时的MemoryError问题

你遇到的MemoryError核心原因是用eval()处理超长布尔函数字符串时的内存过载——eval在解析这类长字符串时,既要承载庞大的字符串本身,还要在内存中构建对应的抽象语法树,当符号数量极大时,内存开销直接触发溢出。而且eval本身还有安全风险,完全不适合处理这类动态生成的超长表达式。

下面给你两个更高效的解决方案:

方案一:用Sympy的parse_expr替代eval

Sympy专门提供了parse_expr函数来解析表达式字符串,它比eval更针对数学/布尔表达式优化,内存效率更高,也更安全。

举个实际例子:

from sympy import symbols, to_nnf, parse_expr

# 假设有10000个符号(数量可任意调整)
total_symbols = 10000
# 批量创建符号,比如x0, x1, ..., x9999
symbol_list = symbols(f'x0:{total_symbols}')

# 假设你的布尔函数字符串是替换后的形式,比如"~(x0 & x1 & ... & x9999)"
bool_func_str = "~(" + " & ".join([f'x{i}' for i in range(total_symbols)]) + ")"

# 用parse_expr替代eval解析表达式
sympy_expr = parse_expr(bool_func_str)
# 转换为否定范式
nnf_result = to_nnf(sympy_expr)

# 查看结果(符号太多时可只看结构)
print(nnf_result)

方案二:直接构建Sympy表达式(推荐)

如果能跳过生成字符串的环节,直接用Sympy的逻辑运算符(And、Not、Or等)构建表达式,完全避免字符串解析的内存开销,这是处理超大符号列表最高效的方式。

示例代码:

from sympy import symbols, to_nnf, And, Not

total_symbols = 10000
symbol_list = symbols(f'x0:{total_symbols}')

# 直接用And组合所有符号,再取Not,完全不用字符串
and_expression = And(*symbol_list)
bool_expression = Not(and_expression)

# 转换为否定范式
nnf_result = to_nnf(bool_expression)

print(nnf_result)

额外提示

如果你的布尔函数是从外部读取的复杂字符串,建议先对字符串做语法分析,拆分出逻辑运算符和变量,再用Sympy的API逐个构建表达式节点,而不是生成超长的整体字符串再解析——这样能最大程度减少内存占用,同时避免eval带来的安全隐患。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:10:08