Domanda

Voglio fare una funzione che converte misti numeri e frazioni (come stringhe) a carri. Ecco alcuni esempi:

'1 1/2' -> 1.5
'11/2' -> 5.5
'7/8' -> 0.875
'3' -> 3
'7.7' -> 7.7

Attualmente sto usando questa funzione, ma penso che potrebbe essere migliorata. Inoltre non gestisce i numeri che sono già in rappresentazione decimale

def mixedtofloat(txt):

    mixednum = re.compile("(\\d+) (\\d+)\\/(\\d+)",re.IGNORECASE|re.DOTALL)
    fraction = re.compile("(\\d+)\\/(\\d+)",re.IGNORECASE|re.DOTALL)
    integer = re.compile("(\\d+)",re.IGNORECASE|re.DOTALL)

    m = mixednum.search(txt)
    n = fraction.search(txt)
    o = integer.search(txt)

    if m:
        return float(m.group(1))+(float(m.group(2))/float(m.group(3)))
    elif n:
        return float(n.group(1))/float(n.group(2))
    elif o:
        return float(o.group(1))
    else:
        return txt

Grazie!

È stato utile?

Soluzione

2.6 ha il fractions modulo. Basta dividere la stringa su spazi, alimentare i pezzi per fractions.Fraction(), chiamata float() contro il risultato, e aggiungere tutti in su.

Altri suggerimenti

La risposta di Ignacio è probabilmente il modo migliore per gestire la cosa, ma se non si utilizza Python 2.6, è possibile costruire una funzione che fa le cose un po 'più semplice, senza dover ricorrere a espressioni regolari. Ecco una semplice e non versione molto robusta ho buttato insieme:

def parse_fraction(fraction):

    def parse_part(part):
        sections = part.split('/')
        if len(sections) == 1:
            return float(sections[0])
        return float(sections[0]) / float(sections[1])

    return sum( parse_part(part) for part in fraction.split() )

Questo ovviamente non è perfetto, perché sarà ancora accettare l'ingresso come '2 1/2 1/2', che sarebbe valutare come 3, poiché riassume essenzialmente un elenco di numeri spazio delimitato mentre valutare ogni come una frazione come necessario.

Se il bastone con la soluzione basata espressioni regolari, si deve sapere che è possibile utilizzare una stringa prima per evitare di dover doppia barra rovesciata tutto. In sostanza, è possibile scrivere:

mixednum = re.compile(r"(\d+) (\d+)/(\d+)")

Il r davanti alla stringa di Python dice di non valutare i caratteri speciali all'interno della stringa, in modo da poter scrivere backslash letterali e saranno trattati come tali. Si noti inoltre che non è necessario per sfuggire alla barra in quanto non è un carattere speciale in Python espressioni regolari (perché non viene utilizzato per segnare i confini del regexp letterale, come in molte lingue). la bandiera re.IGNORECASE, inoltre, non ha molto senso qui, dal momento che include solo le entità numeriche nella regexp, e re.DOTALL è anche privo di significato, dal momento che ci sono punti per la sua applicazione a.

ho scritto la classe Mixed di estendere le frazioni di fare proprio questo. Source è qui .

>>> float(Mixed('6 7/8'))
6.875
>>> float(Mixed(1,1,2)) # 1 1/2
1.5
>>> float(Mixed('11/2')) # 11/2
5.5
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top