2013-10-25 13 views
6

Che è una soluzione Pythonic al seguente?modo efficiente per arrotondare con precisione arbitraria in Python

Sto leggendo un sensore di temperatura che ha .5 risoluzione. Ho bisogno di scriverlo (ha un'uscita cronotermostato programmabile), anche con risoluzione .5.

Così ho scritto questa funzione (Python 2.7) per arrotondare un galleggiante come input per il al più vicino 0,5:

def point5res(number): 
    decimals = number - int(number) 
    roundnum = round(number, 0) 
    return roundnum + .5 if .25 <= decimals < .75 else roundnum 

print point5res (6.123) 

print point5res(6.25) 

print point5res(6.8) 

che funziona bene, le uscite 6.0, 6.5 e 7.0, rispettivamente. È proprio quello che voglio.

Sono relativamente nuovo a Python. La linea

return roundnum + .5 if .25 <= decimals < .75 else roundnum 

mi fa sbavare con ammirazione per i suoi implementatori. Ma è Pythonic?

Edit: dal distacco, ho imparato un po 'di più what is and isn't 'Pythonic'. Il mio codice non lo è. Cmd's anwwer, sotto, è. Grazie!

+0

Provalo per - 5.4. –

+0

o valori negativi in ​​generale, suppongo –

+1

Prova 6.51. Il risultato è 7.5. Ma hai ragione, i confronti concatenati sono una grande caratteristica. E anche la sintassi delle espressioni ternarie, una volta che la "ottieni", è molto bella. –

risposta

6

Essi sono considerati divinatorio se si mantiene le espressioni semplici altrimenti diventa difficile da leggere.

avrei arrotondare al più vicino 0,5 come questo:

round(number*2)/2.0 

o più genericamente:

def roundres(num, res): 
    return round(num/res) * res 
+0

Confrontando gli esempi forniti dall'OP, questo non restituisce gli stessi valori. Questo sta restituendo numeri interi (prova per 6.25) – CDspace

+0

@CDspace quello originale ha avuto problemi ed è per questo che ho pubblicato un'alternativa. Anche la comparazione '==' su un float non si comporterà come previsto. – cmd

+0

Si noti che 'round()' ha cambiato il suo comportamento tra Python 2 e Python 3. 'round (0.5)' è '1' in Python 2 e' 0' in Python 3. Quindi questa soluzione funziona solo in Python 2. Qual è l'utilizzo dell'OP, quindi +1 –

0
return 0.5 * divmod (number, 0.5) [0] if number >= 0 else -0.5 divmod (number, -0.5) [0] 

Questo sembra più bello però:

def roundToHalf (number): 
    ''' Round to nearest half ''' 
    half = 0.5 if number >= 0 else -0.5 
    return half * divmod (number, half) [0] 
Problemi correlati