有没有办法让#34;变异"分数? - 蟒蛇

时间:2016-01-01 23:53:45

标签: python generator mutable fractions

有没有办法让#34;变异" Fraction

我试过这个,但看起来分数中的分子/分母是不可变的。

>>> from fractions import Fraction
>>> x = Fraction(0,1)
>>> numerators = [1,2,3,4,5]
>>> denominators = [9,8,7,6,5]
>>> for n,d in zip(numerators, denominators):
...     x.numerator+= n
...     x.denominator+= d
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
AttributeError: can't set attribute

我一直在这样做,因为我的分子/分母来自另一个返回分数生成器的函数。

>>> inputs = [Fraction(1,9), Fraction(2,8), Fraction(3,7), Fraction(4,6)]
>>> numerators, denominators = zip(*[(f.numerator, f.denominator) for f in inputs])
>>> x = Fraction(sum(numerators), sum(denominators))
>>> x
Fraction(7, 23)

(请注意,我没有添加1/9 + 2/8 + 3/7 + 4/6,我试图对分子求和并除以分母之和)

是否存在&#34;可变的&#34;分数吗

3 个答案:

答案 0 :(得分:5)

numeratordenominator是不可变的,原因有两个:

  1. 其他Python数值类型是不可变的,包括复数,它们还包含两个更简单的数值和任意宽度的数量,例如longDecimal。可变分数将是一个例外。

  2. 能够单独改变分子和分母将有可能使分数无效,例如通过使其非规范化,或通过将分母设置为零。

  3. 换句话说,没有公共API来改变fractions.Fraction对象。如果你真的需要一个单独的分子和分母的总和,这听起来不是很有用,你的第二个代码片段是一个合理的方法。第一个片段的更精确的再现可能如下所示:

    x = Fraction(sum(f.numerator for f in inputs),
                 # add 1 since we start out with 0/1
                 1 + sum(f.denominator for f in inputs))
    

答案 1 :(得分:2)

有趣的想法,但它可以通过一些简单错误的数学来解决:

>>> x = Fraction(0,1)
>>> numerators = [1,2,3,4,5]
>>> denominators = [9,8,7,6,5]
>>> for n,d in zip(numerators, denominators):
...     x += Fraction(n,x.denominator) # "Adding" to the numerator is adding a new fraction.
...     x = x/d # "adding" to the denominator is just dividing by the operand

你可以see this in practice here

正如我在评论中暗示的那样,但是用户4815162342更清楚,Fractions是不可变的,因为 fractions 是不可变的,很像Integers是不可变的,因为这个概念整数的不可变。

7是7是'7'是7,因此为不可变的想法创建一个可变对象是荒谬的。很像3/4是0.75是'四分之三',无论你如何构思它的想法都是一样的,所以制作一个代表静态概念的对象是可变的是没有意义的。

有意义的是使用数学用现在为8的分母修改它们3/4,这不是一件事。分数的加法,乘法或除法更加直观。

答案 2 :(得分:1)

CPython 3.9.2 非公开 API:

>>> from fractions import Fraction
>>> x = Fraction(0,1)
>>> numerators = [1,2,3,4,5]
>>> denominators = [9,8,7,6,5]
>>> for n,d in zip(numerators, denominators):
...     x._numerator+= n
...     x._denominator+= d
>>> print(x)
15/36

请注意,因为这是非公开的方式,将来可能会更改。

https://github.com/python/cpython/blob/master/Lib/fractions.py