替换不推荐的`ractions.gcd()`函数



我想计算以fractions.Fraction实例实现的两个有理数的最大常见分隔线。尽管打印了弃用警告,但它的工作原状如预期的:

In [1]: gcd(Fraction(2, 3), Fraction(2, 3))
/usr/local/bin/ipython:1: DeprecationWarning: fractions.gcd() is deprecated. Use math.gcd() instead.
  #!/usr/local/opt/python3/bin/python3.6
Out[1]: Fraction(1, 6)

查看文档,我可以看到fractions.gcd()确实被弃用,并邀请用户使用math.gcd()。问题是后者不支持有理数:

In [2]: gcd(Fraction(2, 3), Fraction(2, 3))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-c3ad2389f290> in <module>()
----> 1 gcd(Fraction(2, 3), Fraction(2, 3))
TypeError: 'Fraction' object cannot be interpreted as an integer

我可以在更换fractions.gcd()中使用哪个功能?我不是在寻找这里使用的实际算法,而是替换不弃用的功能。

您可能必须写一个。gcd(a/b, c/d) = gcd(a, c)/lcm(b, d),所以这还不错。math不提供lcm,所以我正在使用此处写的。

from fractions import Fraction
from math import gcd
def lcm(a, b):
    """Return lowest common multiple."""
    return a * b // gcd(a, b)
def fraction_gcd(x, y):
    a = x.numerator
    b = x.denominator
    c = y.numerator
    d = y.denominator
    return Fraction(gcd(a, c), lcm(b, d))
print(fraction_gcd(Fraction(2, 3), Fraction(2, 3)))
# 2/3

注意:以下最初由原始海报编辑为问题主体本身。我已经将其移至一个单独的答案中。

@glibdud在他的评论中提到,使用具有合理数字的fractions.gcd()不是预期的行为,肯定不会记录...并且可以使用以下方式轻松实现:

def gcd(numbers):
"""Compute Greastest Common Divisor of rational numbers.
Args:
    numbers: list of rational numbers.
Returns:
    Greatest Common Divisor of rational numbers.
"""
# Treat the two-number case and reduce
def _gcd(a, b):
    if b == 0:
        return a
    if isinstance(a, int) and isinstance(b, int):
        _gcd(b, a % b)
    a = Fraction(a)
    b = Fraction(b)
    return Fraction(gcd([a.numerator, b.numerator]), lcm([a.denominator, b.denominator]))
return reduce(_gcd, numbers)
def lcm(numbers):
    """Compute Least Common Multiple of rational numbers.
    Args:
        numbers: list of rational numbers.
    Returns:
        Least Common Multiple of rational numbers.
    """
    # Treat the two-number case and reduce
    def _lcm(a, b):
        if b == 0:
            return a
        if isinstance(a, int) and isinstance(b, int):
            return a * b // gcd([a, b])
        a = Fraction(a)
        b = Fraction(b)
        return Fraction(lcm([a.numerator, b.numerator]), gcd([a.denominator, b.denominator]))
    return reduce(_lcm, numbers)

该公式在此处得出和解释:https://math.stackexchange.com/questions/44836/rational-numbers-numbers-lcm-and-hcf。

最新更新