将浮点数转换为分数
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 类型。
- 使用以下方法导入:from fractions import Fraction
- 用分数计算你的 f 方程 f = p/q; f = 分数(p/q)
那么也使用字符串转换; 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>0
或y>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']
我正在写 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 类型。
- 使用以下方法导入:from fractions import Fraction
- 用分数计算你的 f 方程 f = p/q; f = 分数(p/q)
那么也使用字符串转换; 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>0
或y>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']