Problemi
- Se nessun valore si ripete?
- Se ci sono due valori con la stessa frequenza massima?
1
Da Python 3.4: statistics.mode(z)
import statistics
NUMERI = [...]
m = statistics.mode(NUMERI)
2
Se l’intervallo di valori è noto, [0, 9]
- utilizza una lista di 10 contatori (inizializzati a zero)
- visita la lista aggiornando i contatori
- individua il contatore più grande
- la moda è l’indice del contatore più grande
def moda(lista):
contatori = [0,0,0,0,0,0,0,0,0,0]
for x in lista:
contatori[x] += 1
max_pos = 0
max_val = contatori[0]
for i in range(1, 10):
x = contatori[i]
if(x > max_val):
max_val = x
max_pos = i
return max_pos
Soluzione 3
Se l’intervallo di valori non è noto
Osserva
- ordina la lista
- utilizza un contatore temporaneo
- conta quante volte compare ciascun valore
- memorizza il valore e la lunghezza della sequenza più lunga
- se nessun elemento compare almeno due volte restituisce errore (None).
LISTA=sorted(NUMERI)
x =LISTA[0]
moda =-1 # moda
modan =-1 # moda - numerosità
modat =x # moda temporanea
modatn=1 # moda temporanea - numerosità
for i in range(1, len(LISTA)):
x=LISTA[i]
if(x == modat):
modatn += 1
else:
if(modatn > modan):
moda =modat
modan=modatn
modat =x
modatn=1
if(modan < 2):
moda=None
Soluzione 4
Evita di trattare il primo valore in modo speciale
LISTA=sorted(NUMERI)
moda =-1 # moda
modan =-1 # moda - numerosità
modat =-1 # moda temporanea
modatn=-1 # moda temporanea - numerosità
for x in LISTA:
if(x == modat):
modatn += 1
else:
if(modatn > modan):
moda =modat
modan=modatn
modat =x
modatn=1
if(modan < 2):
moda=None
Soluzione 5
Per non ordinare la lista utilizza un dizionario (dict)
def valore(coppia):
return coppia[1]
def moda(lista):
d={}
for x in lista:
d[x]=d.get(x,0)+1
lista=list(d.items())
lista.sort(key=valore, reverse=True)
if(lista[0][1] >= 2):
return lista[0][0]
lista1=[1,8,0, 1, 1,9,2, 8]
lista2=[1,8,0,10,100,9,2,80]
print(moda(lista1)) # 1
print(moda(lista2)) # None
Soluzione 6
Utilizza un dizionario migliorato: Counter
import collections
NUMERI=[...]
counter = collections.Counter(NUMERI)
moda = counter.most_common(1)[0][0]
print(moda)