Find least common denominator for a list of fractions in Python
Asked Answered
S

2

8

I have a list of fractions that I need to transform.

from fractions import Fraction

fractions_list=[Fraction(3,14),Fraction(1,7),Fraction(9,14)]

The output should be a list with the numerators for each fraction, followed by the least common denominator for all of them. For above example the result (3/14, 2/14, 9/14) would be represented as follows

[3,2,9,14]

Is there an elegant solution for this? All I can think of involves a lot of intermediate lists to store some variables, and scales horribly.

Suspense answered 6/4, 2020 at 6:53 Comment(2)
numpy.lcm would work.Hodge
Good news: There is math.lcm(*integers) for this in Python 3.9+ (Oct 2020).Weakly
M
11
import numpy as np

fractions_list=[Fraction(3,14),Fraction(1,7),Fraction(9,14)]

lcm = np.lcm.reduce([fr.denominator for fr in fractions_list])

vals = [int(fr.numerator * lcm / fr.denominator) for fr in fractions_list]
vals.append(lcm)
Miliary answered 6/4, 2020 at 7:9 Comment(0)
W
1

Python 3.9 (released on October 5, 2020), added the function math.lcm(*integers) which supports an arbitrary amount of integers as arguments. And, as Wikipedia tells us, this is all we need:

In mathematics, the lowest common denominator or least common denominator (abbreviated LCD) is the lowest common multiple of the denominators of a set of fractions.

So we don't need to import numpy for this anymore.

from fractions import Fraction
import math

# Create Fractions from string arguments:
fracs = [Fraction(f) for f in ["3/14", "1/7", "9/14"]]

# Calculate lowest common denominator:
lcd = math.lcm(*[f.denominator for f in fracs])

# Print numerators of expanded fractions with common denominator appended:
print([f.numerator * lcd // f.denominator for f in fracs] + [lcd])

Please note that we use integer division in the last line, so we don't need to cast division results back to int (as shown in Tom Ron's answer).

Weakly answered 9/9 at 12:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.