[Python] media di un generatore

Marco Buttu mbuttu a oa-cagliari.inaf.it
Ven 13 Dic 2013 10:41:38 CET


On 12/11/2013 08:52 PM, Giovanni Porcari wrote:
> Se mi limito a rendere sum(x)/x.count() delego alla matematica
> del tipo che totalizzo il compito di definire la media.
> Se invece scrivo float rischio di essere meno generico
> e di imporre che la media sia di interi o di float.
>
> Concordi ?
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)
...
 >>> 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:

 >>> import statistics # Python 3.4 :)
 >>> statistics.mean([1e30, 1, 3, -1e30])
1.0

La funzione statistics.mean() prende come argomento un oggetto 
iterabile, quindi la soluzione al problema dell'OP, a partire da Python 
3.4 e' banale :) Basta passare il generatore, o l'oggetto iterabile, a 
statistics.mean():

 >>> statistics.mean(i for i in [1e30, 1, 3, -1e30])
1.0
 >>> d = {1e30: 'a', 1: 'b', 3: 'c', -1e30: 'd'}
 >>> statistics.mean(d)
1.0

[1] http://www.python.org/dev/peps/pep-0450/

-- 
Marco Buttu

INAF-Osservatorio Astronomico di Cagliari
Via della Scienza n. 5, 09047 Selargius (CA)
Phone: 070 711 80 217
Email: mbuttu a oa-cagliari.inaf.it



Maggiori informazioni sulla lista Python