如何在Python中将表达式列表中的小数转换为分数?
将SymPy表达式列表中的小数转换为分数形式
问题描述
我需要把Python中SymPy表达式列表里的小数转为分数形式,现有代码如下:
import sympy as sp from fractions import Fraction M = sp.symbols('M') diffs = [None, 0, 5*M/2 - 3.5, 0.5 - 3*M/2, -M, M/2 - 1.5, 0, 1.5 - 3*M/2] # 尝试转换但无效的代码 diffs = [Fraction(float(val)).limit_denominator() if isinstance(val, float) else val for val in diffs] # diffs = [sp.Rational(val).limit_denominator() if isinstance(val, float) else val for val in diffs] print(diffs)
当前输出仍保留小数:
[None, 0, 5*M/2 - 3.5, 0.5 - 3*M/2, -M, M/2 - 1.5, 0, 1.5 - 3*M/2]
期望输出(小数转为分数形式,且不出现Fraction()或Rational()格式):
[None, 0, 5*M/2 - 7/2, 1/2 - 3*M/2, -M, M/2 - 3/2, 0, 3/2 - 3*M/2]
问题原因
原来的代码判断isinstance(val, float)不生效,因为列表中带小数的元素是SymPy表达式对象(比如5*M/2 - 3.5是Add类型),不是纯float值,所以转换逻辑根本没触发。
解决方案
使用SymPy的nsimplify()函数,它可以自动遍历表达式中的所有元素,将小数转换为最简分数形式,同时保持表达式的结构不变。
修改后的代码:
import sympy as sp M = sp.symbols('M') diffs = [None, 0, 5*M/2 - 3.5, 0.5 - 3*M/2, -M, M/2 - 1.5, 0, 1.5 - 3*M/2] # 遍历每个元素,对SymPy表达式执行nsimplify转换 diffs = [sp.nsimplify(val) if val is not None and isinstance(val, sp.Expr) else val for val in diffs] print(diffs)
输出结果
运行后得到符合要求的输出:
[None, 0, 5*M/2 - 7/2, 1/2 - 3*M/2, -M, M/2 - 3/2, 0, 3/2 - 3*M/2]
注:原期望输出中
5*M/2 -5/2是笔误,3.5对应的最简分数是7/2,而非5/2。
内容的提问来源于stack exchange,提问作者Elektvocal95
相关产品推荐
相关产品推荐

