Как преобразовать символы Unicode в float в Python?

Я разбираю веб-страницу, которая имеет Unicode-представления фракций. Я хотел бы иметь возможность напрямую перенести эти строки и преобразовать их в float. Например:

"⅕" станет 0.2

Любые предложения о том, как это сделать в Python?

Ответ 1

Вы хотите использовать модуль unicodedata:

import unicodedata
unicodedata.numeric(u'⅕')

Это напечатает:

0.20000000000000001

Если символ не имеет числового значения, то unicodedata.numeric(unichr[, default]) будет возвращать значение по умолчанию или если значение по умолчанию не задано, будет повышаться значение ValueError.

Ответ 2

Поскольку существует только фиксированное число фракций, определенных в Unicode, словарь кажется подходящим:

Fractions = {
    u'¼': 0.25,
    u'½': 0.5,
    u'¾': 0.75,
    u'⅕': 0.2,
    # add any other fractions here
}

Обновление: модуль unicodedata является гораздо лучшим решением.

Ответ 3

Возможно, вы можете разложить дробь с помощью "unicodedata" модуля, а затем искать FRACTION SLASH character, а затем это просто вопрос простого деления.

Например:

>>> import unicodedata
>>> unicodedata.lookup('VULGAR FRACTION ONE QUARTER')
u'\xbc'
>>> unicodedata.decomposition(unicodedata.lookup('VULGAR FRACTION ONE QUARTER'))
'<fraction> 0031 2044 0034'

Обновление: Я оставлю этот ответ здесь для справки, но используя unicodedata.numeric() в соответствии с ответом Карла, это гораздо лучшая идея.

Ответ 4

В Python 3.1 вам не нужно "u", и оно будет производить 0,2 вместо 0.20000000000000001 .

>>> unicodedata.numeric('⅕')
0.2

Ответ 5

Я заявляю очевидное здесь, но это очень просто расширить это для случаев, когда люди пишут "1¾", что означает "1.75", поэтому я просто собираюсь поделиться им здесь для быстрой справки:

import unicodedata

# Assuming that the unicode is always the last character. You always going to see stuff like "3¼", or "19¼" whereas stuff like "3¼5"
# does not have a clear interpretation 

def convertVulgarFractions(vulgarFraction):

    if (len(vulgarFraction) == 1):
        return unicodedata.numeric(vulgarFraction)

    if (len(vulgarFraction) > 1) & (not (vulgarFraction[:len(vulgarFraction)-1].isdigit())):
        raise ArithmeticError("The format needs to be numbers ending with a vulgar fraction. The number inserted was " + 
                              str(vulgarFraction))

    if vulgarFraction[len(vulgarFraction)-1].isdigit():
        return float(vulgarFraction)
    else:
        return float(vulgarFraction[:len(vulgarFraction)-1]) + unicodedata.numeric(vulgarFraction[len(vulgarFraction)-1])

Ответ 6

Хотя не совсем то, что было задано, возможно, кто-то хочет, чтобы он преобразовывался во фракцию, а не в float. В конце концов, фракция представляет собой то, что она действительно представляет.

unicodedata.normalize("NFKC", "⅕") приводит к "1⁄5". В настоящее время это не понимается fractions.Fraction, который ожидает фракцию, описываемую /, а не . Однако это легко заменить:

In [313]: def unifrac_to_frac(s):
     ...:     return fractions.Fraction(unicodedata.normalize("NFKC", s).replace("⁄", "/"))
     ...: 

In [315]: unifrac_to_frac("⅕")
Out[315]: Fraction(1, 5)

In [316]: unifrac_to_frac("½")
Out[316]: Fraction(1, 2)

In [317]: unifrac_to_frac("↉")
Out[317]: Fraction(0, 1)