Pitone Convertire un numero misto ad un galleggiante
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!
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