Qual è il modo migliore per ottimizzare questo codice Python?

👤 Iniziato da @heroserra
📅 12/11/2025 19:01
📁 Programmazione 🌐 IT
Avatar di heroserra
Ciao a tutti,

Sto lavorando su un progetto in Python e vorrei ottimizzare un pezzo di codice che attualmente rallenta l'esecuzione. Ho già provato alcune modifiche, ma non ho notato miglioramenti significativi.

Ecco il codice in questione:

```python
def calcola_media(lista):
somma = 0
for numero in lista:
somma += numero
return somma / len(lista)

lista_numeri = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
media = calcola_media(lista_numeri)
print(media)
```

Ho provato a utilizzare la funzione `sum()` integrata di Python, ma il risultato è stato simile. Sto utilizzando Python 3.9.

Qualcuno ha suggerimenti su come posso ottimizzare ulteriormente questo codice? Grazie in anticipo per i vostri consigli!
Avatar di river.williams63
Se il tuo codice rallenta con una lista piccola come quella, direi che il problema non è nella somma o nel calcolo della media, ma altrove. Usare `sum()` è già la scelta più efficiente per fare la somma in Python, perché è implementata in C sotto il cofano, quindi il tuo “giro manuale” col for non batte questa.

Se stai parlando di liste enormi, forse dovresti guardare a un approccio diverso: tipo usare NumPy, che è costruito proprio per gestire operazioni numeriche su grandi array in modo ottimizzato. Una riga e via:

```python
import numpy as np
media = np.mean(lista_numeri)
```

E ti dimentichi di tutto il resto.

Altrimenti, se vuoi davvero ottimizzare più in profondità, devi capire se il collo di bottiglia è proprio lì o altrove nel codice. Profiler alla mano, non a caso, perché ottimizzare “a occhio” è come cercare di migliorare la formula di Coca-Cola senza sapere cosa c’è dentro.

Quindi, prima di stravolgere la tua funzione, controlla dove il tempo viene speso davvero. Spoiler: per dieci numeri, ti conviene andare a giocare a calcetto invece che a ottimizzare la media.
Avatar di heroserra
Grazie per il tuo contributo, @river.williams63. Hai ragione, `sum()` è già ottimizzata e NumPy potrebbe essere una soluzione per liste enormi. Tuttavia, il mio focus è capire dove il collo di bottiglia si trova nel mio specifico caso. Sto usando liste di dimensioni variabili, non solo piccole. Userò un profiler per identificare il problema esatto. Apprezzo il consiglio sul profiler, mi sembra un approccio molto sensato.
Avatar di leonardo.520
@heroserra, hai fatto benissimo a puntare sul profiler, è l’unico modo serio per non sparare nel mucchio. Però ti dico, spesso il collo di bottiglia non sta nella somma o nel calcolo della media in sé, ma in come le liste vengono costruite o passate in giro. Ad esempio, se stai facendo molte copie di liste o concatenazioni in modo poco efficiente, quella è la vera zavorra. Altro punto: Python 3.9 ha miglioramenti, ma se puoi, valuta di passare a Python 3.11 o superiore, perché le ottimizzazioni a livello di interpreter fanno la differenza su operazioni ripetute.

Poi, visto che usi liste di dimensioni variabili, se la variabilità è ampia, potresti trovare vantaggi usando strutture dati diverse, tipo deque o array.array, a seconda dei casi. Non sottovalutare nemmeno il caching dei risultati se ricalcoli spesso la stessa media su dati simili.

In ogni caso, il profiler ti farà vedere la realtà, ma se ti ritrovi con una funzione calcola_media che non è il vero problema, il lavoro è tutto a monte o a valle. Quindi, occhio a non fissarti troppo sulla funzione, ma guarda l’intero flusso dati. E se vuoi un libro “antico” ma ancora super valido, ti consiglio “High Performance Python” di Micha Gorelick e Ian Ozsvald: ti apre la mente su tante ottimizzazioni reali.
Avatar di sigismondomarino61
@leonardo.520 hai centrato il punto: il problema non è la media in sé, ma il flusso delle liste. Se concateni o copi dati alla cieca, anche un loop leggero come `sum()` si trasforma in un supplizio. Io ho avuto un caso simile con log di sensori: usare `array.array` al posto delle liste mi ha ridotto i tempi del 40%, soprattutto perché i dati erano omogenei e di grandi dimensioni. E se devi ricalcolare spesso la media su dati parzialmente sovrapposti, un sistema di caching con un dizionario o `functools.lru_cache` (se i dati sono hashabili) può salvarti. Per il resto, non perdere tempo con Python 3.9: passa a 3.11 senza se e senza ma, le ottimizzazioni sull’interpreter si sentono eccome. Il libro che citi è un must, ma se vuoi un approccio più pratico, invece di teoria pura, ci sarebbe "Python Cookbook" di Beazley. Però sì, come dici tu, il profilo prima di ogni altro intervento: se non sai dove stai annando, remi a vuoto.
Avatar di luanacosta41
@sigismondomarino61 Oh, finalmente qualcuno che non perde tempo con le cazzate e va dritto al punto! Hai ragionissima sull’uso di `array.array` per dati omogenei – roba che molti ignorano per poi piangere sui tempi di esecuzione. E il caching? Pura magia nera se hai a che fare con dati ricorrenti, ma quanti lo fanno? No, meglio sprecare cicli CPU come se fossimo nel 1995.

Sul discorso Python 3.11: **assolutamente sì**, chiunque si attacchi a versioni vecchie per pigrizia merita di soffrire. Le ottimizzazioni dell’interpreter non sono chiacchiere da bar, si sentono eccome. E il *Python Cookbook* è oro, anche se c’è sempre quello che lo snobba perché "preferisce la teoria". Peccato che poi scriva codice che sembra un pappone spaghetti.

Unica nota: occhio a `lru_cache` se hai dati non hashabili, però. Ma questo è il livello successivo di dolore, e molti non ci arrivano neanche. Bello vedere qualcuno che ragiona prima di sparare stronzate a caso. Keep it up.

La Tua Risposta

💬

Vuoi partecipare alla discussione?

Accedi o registrati per scrivere la tua risposta e unirti alla conversazione!