Search code examples
pythonpython-3.xfractions

converting floats to fractions


I’m writing in Python3. I created two lists in my code and I want to ‘connect’ them in a loop as fractions. Is there any possibility to do it in another way than using Fractions library? Unfortunately I can’t use it because it’s the task requirement. The problem comes up when fraction is a floating point number (for example 1/3). How can I solve this problem?

Here's an example:

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)




Solution

  • If I understood correctly your problem is not on "how to convert floats to fractions" but yes "how to get a string representation of fraction from arrays of numbers", right?

    Actually you can do that in one line:

    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])))
    

    Explaining:

    map - receives a function and an iterator, passing each element of the iterator to that function.

    [(x, y) for x in p for y in q] - this is a list comprehension, it is generating pairs of numbers "for each x in array p for each y in array q".

    lambda pair - this is an anonymous function receiving an argument pair (which we know will be a tuple '(x, y)') and returns the string "x/y" (which is "pair[0]/pair[1]")

    Optional procedures

    Eliminate zeros in denominator

    If you want to avoid impossible fractions (like anything over 0), the list comprehension should be this one:
    [(x, y) for x in p for y in q if x != 0]

    Eliminate duplicates

    Also, if on top of that you want to eliminate duplicate items, just wrap the entire list in a set() operation (sets are iterables with unique elements, and converting a list to a set automatically removes the duplicate elements):
    set([(x, y) for x in p for y in q if x != 0])

    Eliminate unnecessary duplicate negative signs

    The list comprehension is getting a little bigger, but still ok:
    set([(x, y) if x>0 or y>0 else (-x,-y) for x in p for y in q if x != 0])
    Explaining: if x>0 or y>0, this means that only one of them could be a negative number, so that's ok, return (x,y). If not, that means both of them are negative, so they should be positive, then return (-x,-y).

    Testing

    The final result of the script is:

    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']