将浮点数转换为分数

converting floats to fractions

我正在写 Python3。 我在我的代码中创建了两个列表,我想将它们作为分数循环“连接”起来。除了使用 Fractions 库之外,还有其他方法吗?不幸的是我不能使用它,因为这是任务要求。当分数是浮点数(例如 1/3)时,问题就出现了。 我怎么解决这个问题?

这是一个例子:

p = [1,2,3]
q = [3,5,9]

frac = []
    for i in p:
      for j in q:
        f = i/j
        if f not in frac:
          frac.append(f)



(0.33).as_integer_ratio() 可以解决您的问题。显然 0.33 将被替换为任何 float.

根据 this question

def float_to_ratio(flt):
    if int(flt) == flt:
        return int(flt), 1
    flt_str = str(flt)
    flt_split = flt_str.split('.')
    numerator = int(''.join(flt_split))
    denominator = 10 ** len(flt_split[1])
    return numerator, denominator

这也是一种解决方法。

您可以使用 fractions.Fraction 类型。

  1. 使用以下方法导入:from fractions import Fraction
  2. 用分数计算你的 f 方程 f = p/q; f = 分数(p/q)
  3. 那么也使用字符串转换; f = str(分数(p/q))

    from fractions import Fraction
    f = str(Fraction(p/q))
    

您可以通过下面的简单代码使用循环来计算分数

x = 0.6725
a = 0
b = 1
while (x != a/b):
    if x > a/b:
        a += 1
    elif x < a/b:
        b += 1
print(a, b)

a 和 b 的结果将是

269 400

如果我理解正确,你的问题不在 "how to convert floats to fractions" 上,而是在 "how to get a string representation of fraction from arrays of numbers" 上,对吗?

实际上你可以在一行中完成:

p = [1,2,3]
q = [3,5,9]

list(map(lambda pair: f"{pair[0]}/{pair[1]}", [(x, y) for x in p for y in q])))

解释:

map - 接收一个函数和一个迭代器,将迭代器的每个元素传递给该函数。

[(x, y) for x in p for y in q] - 这是一个 list comprehension,它正在生成数字对 "for each x in array p for each y in array q".

lambda pair - 这是一个 anonymous function 接收参数 pair (我们知道这将是一个 tuple '(x, y)')和 returns 字符串 "x/y"(即 "pair[0]/pair[1]")

可选程序

消除分母中的零

如果你想避免不可能的分数(比如任何大于 0 的分数),列表理解应该是这个:
[(x, y) for x in p for y in q if x != 0]

消除重复项

此外,如果除此之外您还想消除重复项,只需将整个列表包裹在 set() 操作中(集合是具有唯一元素的可迭代对象,将列表转换为集合会自动删除重复元素):
set([(x, y) for x in p for y in q if x != 0])

消除不必要的重复负号

列表理解变大了一点,但还可以:
set([(x, y) if x>0 or y>0 else (-x,-y) for x in p for y in q if x != 0])
解释:如果x>0y>0,这意味着其中只有一个可能是负数,所以没关系,return(x,y)。如果不是,那就说明两者都是负数,所以应该是正数,那么return(-x,-y).

测试

脚本的最终结果是:

p = [1, -1, 0, 2, 3]
q = [3, -5, 9, 0]

print(list(map(lambda pair: f"{pair[0]}/{pair[1]}", set([(x, y) if x>0 or y>0 else (-x,-y) for x in p for y in q if y != 0]))))


# output:
# ['3/-5', '2/-5', '1/5', '1/-5', '0/3', '0/9', '2/3', '2/9', '3/3', '-1/3', '-1/9', '0/5', '3/9', '1/3', '1/9']