Reputation: 693
I want to take the reciprocal of Fraction
in python, and do so in-place. The Fraction
class does not provide a method for doing so (in my knowledge). I tried to just swap numerator and denominator:
f = Fraction(2, 3)
f.numerator, f.denominator = f.denominator, f.numerator
but it resulted in an AttributeError: can't set attribute
.
I've also used the method of just constructing an new Fraction
:
f = Fraction(2, 3)
f = Fraction(f.denominator, f.numerator)
which does in fact work, but creating a new object and deleting the old one doesn't seem very 'pythonic', i.e. unnecessarily complex. Is there a better way to take the reciprocal?
Upvotes: 1
Views: 737
Reputation: 14233
from fractions import Fraction
spam = Fraction(2, 3)
eggs = spam ** -1
print(repr(eggs))
output
Fraction(3, 2)
EDIT:
As suggested in comments by @martineau 1 / spam
also works:
from fractions import Fraction
spam = Fraction(2, 3)
eggs = 1 / spam
print(repr(eggs))
Upvotes: 3
Reputation: 123473
Fractions
are immutable like many (all?) Python numbers, which is why you can't change their attributes. The workaround is to define a function that creates and returns a new instances of the class based on the attributes of the one passed to it. Two ways of doing this are shown below.
from fractions import Fraction
def reciprocal(f):
""" Return reciprocal of argument (an instance of Fraction). """
return Fraction(f.denominator, f.numerator)
# Alternative implementation.
reciprocal = lambda f: Fraction(f.denominator, f.numerator)
f = Fraction(2, 3)
print(f) # -> 2/3
print(repr(f)) # -> Fraction(2, 3)
r = reciprocal(f)
print(r) # -> 3/2
print(repr(r)) # -> Fraction(3, 2)
Upvotes: 1