我正在尝试转换格式
的字符串'[[2, 3.1], [4/5, 5/6]]'
到fractions模块的2d Fraction对象列表。在上面给出的特定情况下,结果应该是
[[Fraction(2, 1), Fraction(31, 10)], [Fraction(4, 5), Fraction(5, 6)]]
字符串中的间距不一定像我写的那样均匀(没有空格,多余的空格,不均匀的空格数等)。
我可以通过剥离外部括号,在']'
分割字符串,从结果列表中删除空字符串,从列表中的每个字符串的开头删除任何非数字,在几个步骤中执行此操作while循环,用逗号分隔每个字符串,最后将嵌套列表的元素转换为Fractions。
但这相当麻烦。对此有更好的解决方案吗?
答案 0 :(得分:3)
您可以使用正则表达式将字符串中的数字文字转换为对Fraction
的调用。转换后,您可以在结果上调用eval
以获取适当的嵌套列表。
您不需要以特殊方式处理除法运算,因为如果我们只将分子和分母转换为Fraction
个对象,那么它们将完全按照您的意愿运行(所以4/5
变为Fraction("4")/Fraction("5")
,其评估为Fraction(4, 5)
)。
转换应在您传递给Fraction
的数字周围加上引号,因为这会阻止eval
将带小数点的数字解析为float
个实例(这通常会导致精度损失) )。 Fraction
可以从字符串中进行解析,并且它不会失去任何精度,因为所有有限长度的十进制数都具有精确的Fraction
表示。
代码:
import re
from fractions import Fraction
input_text = '[[2, 3.1], [4/5, 5/6]]'
transformed_text = re.sub(r'([\d.]+)', r'Fraction("\1")', input_text)
results = eval(transformed_text)
print(results) # [[Fraction(2, 1), Fraction(31, 10)], [Fraction(4, 5), Fraction(5, 6)]]
答案 1 :(得分:1)
我想出了一个漂亮的代码片段,可以帮助你解决它:
from fractions import Fraction
input_string = '[[2, 3.1], [4/5, 5/6]]'
parsed_input = [item for item in ''.join((char if char in '0123456789./' else '-') for char in input_string).split('-') if item]
output_array = [Fraction(i).limit_denominator(10) for i in parsed_input]
我希望这会有所帮助。如果含糊不清,请使用评论部分。
答案 2 :(得分:0)
import ast
import re
from fractions import Fraction
input_text = '[[2, 3.1], [1e100, -5/6]]'
transformed_text = ast.literal_eval(re.sub(r'([^,\[\]\s]+)', r'"\1"', input_text))
transformed_text = [[ Fraction(j) for j in i] for i in transformed_text ]
Fraction(...)
可以处理许多不同的输入形式;请在此处https://docs.python.org/3/library/fractions.html#fractions.Fraction加上说明Fraction
构造函数现在接受float
和decimal.Decimal instances
。ast.literal_eval
不是eval