将字符串转换为分数列表

时间:2018-03-31 03:02:36

标签: python python-3.x list

我正在尝试转换格式

的字符串
'[[2, 3.1], [4/5, 5/6]]'

到fractions模块的2d Fraction对象列表。在上面给出的特定情况下,结果应该是

[[Fraction(2, 1), Fraction(31, 10)], [Fraction(4, 5), Fraction(5, 6)]]

字符串中的间距不一定像我写的那样均匀(没有空格,多余的空格,不均匀的空格数等)。

我可以通过剥离外部括号,在']'分割字符串,从结果列表中删除空字符串,从列表中的每个字符串的开头删除任何非数字,在几个步骤中执行此操作while循环,用逗号分隔每个字符串,最后将嵌套列表的元素转换为Fractions。

但这相当麻烦。对此有更好的解决方案吗?

3 个答案:

答案 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 ]