[Python] media di un generatore

Dario Bertini berdario a gmail.com
Ven 13 Dic 2013 11:02:46 CET


2013/12/13 Marco Buttu <mbuttu at oa-cagliari.inaf.it>:
>
> Per completare tutta la chiacchierata, aggiungo qualche utile considerazione
> sulla media. Partiamo da questo esempio:
>
>>>> from __future__ import division
>>>> def mean(data):
> ...     return sum(data)/len(data)
> ...

+1 per l'utilizzo di __future__.division

io do sempre per scontato che si utilizzi Python3, e trovo
disorientante che la gente si trovi ancora ad affrontare problemi che
ci sono solo con Python2


>>>> mean([10, 1, 3, -10])
> 1.0
>>>> mean([10**30, 1, 3, -10**30])
> 1.0
>
> Tutto va come dovrebbe, quindi possiamo generalizzare? Purtroppo no... Ecco
> cosa accade con i float:
>
>>>> mean([1e30, 1, 3, -1e30]) # Floating point
> 0.0
>
> Lo standard floating point e' una brutta bestia, e capita di vedere errori
> logici a riguardo commessi anche da persone che programmano da anni. Per
> questo motivo, visto che alcune funzioni statistiche (come ad esempio la
> media) vengono usate praticamente da tutti, si e' deciso di introdurre
> (Python 3.4) nella libreria standard [1] il modulo statistics:
>

Amen, questo però non pare essere un problema con i float

>>> print(mean([Decimal("1e30"), 1, 3, Decimal("-1e30")]))
0E+3

(con Fraction invece funziona come ci aspetta)

già che ci siamo, ricordo d'aver letto Guido scrivere che al contrario
di ABC, si è deciso di non rendere il tipo dei numeri con virgola
mobile, uno a precisione arbitraria, ed usare invece i float, perchè
abusandone poi si verficavano problemi di performace in codebase dove
Decimal era onnipresente

capisco l'idea del "usare un tipo dove serve veramente", ma mi pare
una scelta veramente strana... in Python non si predilige quasi mai le
performance a scapito della correttezza (altrimenti useremmo tutti C)

qualcuno è a conoscenza di maggiori dettagli su questa scelta?

-- 
xmpp: berdario at gmail.com
bitmessage: BM-2cTYXfGiSTsnx3righ6aHcJSWe4MV17jDP
gpg fingerprint: 3F8D53518012716C4EEF7DF67B498306B3BF75A0 (used just
for signing commits)


Maggiori informazioni sulla lista Python