1

数分前、キーが分数 (単純な分数) である辞書の並べ替えについて質問しました。

分数モジュールを使用する必要があることはわかっていますが、分数の分母が分数自体の場合、モジュールは機能しません。

例えば

「1/1.6」、「1/2.5」

>>> import fractions
>>> f = '1/1.6'
>>> fractions.Fraction(f)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/fractions.py", line 125, in __new__
    numerator)
ValueError: Invalid literal for Fraction: '1/1.6'

何か案は ??

4

2 に答える 2

6

Python のfractionsモジュールは、近似浮動小数点数ではなく、正確な有理数 (Fraction、Decimal、またはその他) で動作するように設計されています。floatそのため、意図的にs のペア、または 2 つの float で構成される文字列部分を取るコンストラクターはありません。

ただし、単一の 、または単一の文字列 floatを取るコンストラクターがありますfloatそれが本当に欲しいことがわかっている場合は、次のことができます。

>>> f = Fraction('1') / Fraction('1.6')
Fraction(5, 8)
>>> f = Fraction(1) / Fraction(1.6)
Fraction(2251799813685248, 3602879701896397)

Fraction('1.6')おそらく、が とは非常に異なるものを返すことに気付くでしょうFraction(1.6)。前者は、「1.6」としてレンダリングされる最も単純な分数を返します。後者は、不正確な float 値 1.6 に一致する最も単純な小数を返します。

そう:

>>> a = ['1/1.6', '1/2.5', '3/4', '1.1/10']
>>> nd = [x.split('/') for x in a]
>>> nd
[['1', '1.6'], ['1', '2.5'], ['3', '4'], ['1.1', '10']]
>>> f = [Fraction(x[0]) / Fraction(x[1]) for x in nd]
>>> f
[Fraction(5, 8), Fraction(2, 5), Fraction(3, 4), Fraction(11, 100)]
>>> sorted(f)
[Fraction(11, 100), Fraction(2, 5), Fraction(5, 8), Fraction(3, 4)]

すべてをまとめると、文字列のリストを小数の分数としての同等の値で並べ替えたい場合は、次のようになります。

>>> def fractionize(s):
>>>   n, d = s.split('/')
>>>   return Fraction(n) / Fraction(d)
>>> sorted(a, key=fractionize)
['1.1/10', '1/2.5', '1/1.6', '3/4']

もちろん、この種のことをたくさん行う必要がある場合は、独自の分数モジュールを作成することをお勧めします (または、既に作成されたものについては、何千ものオンライン レシピを参照してください)。あなたが望むように、あなたはそのfractionize機能を必要としません。

于 2012-09-27T23:43:25.723 に答える
2

eval次のように、配列のすべての要素を指定できます。

a = ["1/1.6","1/2.5","6+7","-1*3"]
sorted(a, key=eval)

戻り値

['-1*3', '1/2.5', '1/1.6', '6+7']

少し遅いかもしれませんが、うまくいくはずです。

python3分数のようなものが1/3正しく機能する必要があることに注意してください(python2/では整数除算であり、浮動小数点除算ではないためです。修正する'1.0*'には、すべての文字列の先頭に追加できます)。

于 2012-09-27T23:29:14.290 に答える