如何从浮点数列表中获取Python中整数的最大公约数?

nic*_*sar 1 python math integer list

我有一个浮动列表

l1 = [10.0, 50.0, 100.0]
l2 = [0.1, 0.5, 1.0]
l3 = [20.0, 100.0, 200.0]
Run Code Online (Sandbox Code Playgroud)

全部应该返回:

i = [1, 5, 10]
Run Code Online (Sandbox Code Playgroud)

以较小的作为基数乘数来获取整数的最有效方法是什么?或它们的倍数(如果不可能的话)

例子:

n1 = [0.2, 0.3, 0.6]
Run Code Online (Sandbox Code Playgroud)

应该返回

i = [2, 3, 6]
Run Code Online (Sandbox Code Playgroud)

 n2 = [1424.56, 2136.84, 4985.96]
Run Code Online (Sandbox Code Playgroud)

应该返回:

 i = [ 2, 3, 7] # 712.28 = 1
Run Code Online (Sandbox Code Playgroud)

我正在使用,value / min(l1)但它不适用于第二种情况和第三种情况

Joh*_*ica 5

您可以将所有数字转换为整数,然后将每个数字除以其最大公约数 (GCD)。最好避免使用浮点数,因为它们无法准确表示许多小数。分数模块非常适合此目的:它可以处理小数和有理数,例如 1/3 和 2/7。

#!/usr/bin/env python3

from fractions import Fraction
from functools import reduce
from math import gcd

def lcm(a, b):
    return a * b // gcd(a, b)

def common_integer(*numbers):
    fractions = [Fraction(n).limit_denominator() for n in numbers]
    multiple  = reduce(lcm, [f.denominator for f in fractions])
    ints      = [int(f * multiple) for f in fractions]
    divisor   = reduce(gcd, ints)
    return [int(n / divisor) for n in ints]
Run Code Online (Sandbox Code Playgroud)

这将每个数字转换为有理分数,然后将它们乘以分母的最小公倍数 (LCM)。这有效地放大了它们,因此它们都是整数。然后将它们除以它们的集体 GCD,尽可能缩小它们。

例子:

>>> common_integer('0.2', '0.3', '0.6')
[2, 3, 6]
>>> common_integer('1424.56', '2136.84', '4985.96')
[2, 3, 7]
>>> common_integer('2/7', '18/42', '1/3')
[6, 9, 7]
Run Code Online (Sandbox Code Playgroud)

(使用limit_denominator()允许传入浮点数,即使是不精确的浮点数。并不完全推荐,但您可以省略引号并传递代替0.2'0.2'代替1/3'1/3'