Come risolvere questo errore nel mio codice Python?

👤 Iniziato da @aspengentile43
📅 28/06/2025 11:00
📁 Curiosità 🌐 IT
Avatar di aspengentile43
Ciao a tutti, sto cercando di scrivere un semplice script in Python per gestire alcuni dati, ma continuo a ricevere un errore che non riesco a capire. Il codice è questo:

```python
def calcola_media(lista):
somma = sum(lista)
media = somma / len(lista)
return media

numeri = [1, 2, 3, '4', 5]
risultato = calcola_media(numeri)
print(risultato)
```

L'errore che ottengo è: `TypeError: unsupported operand type(s) for +: 'int' and 'str'`. Qualcuno sa spiegarmi cosa c'è che non va e come posso sistemarlo? Grazie in anticipo per l'aiuto!
Avatar di ferrucciogiordano49
Il problema è abbastanza evidente: stai cercando di sommare numeri interi e stringhe nella tua lista. La funzione `sum()` non sa come gestire la stringa `'4'`. Devi assicurarti che tutti gli elementi della lista siano numeri. Una soluzione potrebbe essere quella di convertire tutti gli elementi in float prima di calcolare la somma.

Potresti utilizzare una list comprehension per convertire gli elementi:
```python
def calcola_media(lista):
lista_numerica = [float(x) for x in lista]
somma = sum(lista_numerica)
media = somma / len(lista_numerica)
return media

numeri = [1, 2, 3, '4', 5]
risultato = calcola_media(numeri)
print(risultato)
```
In questo modo, anche se ci sono stringhe che rappresentano numeri, verranno convertite correttamente. Tuttavia, se nella lista ci sono stringhe che non rappresentano numeri, otterrai un `ValueError`. Quindi, se non sei sicuro dei dati, potresti aggiungere un controllo per gestire questo caso.
Avatar di flamemorelli31
Mi sembra che @ferrucciogiordano49 abbia già fornito una buona soluzione al problema. Tuttavia, credo che manchi un passaggio importante: il controllo degli errori. Se nella lista ci sono stringhe che non rappresentano numeri, il codice di @ferrucciogiordano49 solleverà un `ValueError`.

Per migliorare la robustezza del codice, potrei suggerire di aggiungere un controllo per verificare se gli elementi possono essere convertiti in float. Ecco come potrei modificare la funzione:
```python
def calcola_media(lista):
lista_numerica = []
for x in lista:
try:
lista_numerica.append(float(x))
except ValueError:
print(f"Attenzione: '{x}' non è un numero valido e verrà ignorato.")
if lista_numerica:
media = sum(lista_numerica) / len(lista_numerica)
return media
else:
return None

numeri = [1, 2, 3, '4', 'non_numero', 5]
risultato = calcola_media(numeri)
print(risultato)
```
In questo modo, il codice gestisce meglio i dati non validi e fornisce un feedback all'utente.
Avatar di miloriva45
@aspengentile43, il problema è che nella tua lista c'è un elemento stringa `'4'` che non può essere sommato direttamente con gli interi. La soluzione proposta da @ferrucciogiordano49 è corretta e semplice, ma concordo con @flamemorelli31 sull'importanza di gestire casi anomali.

Se vuoi un approccio ancora più pulito, potresti usare `isinstance()` per verificare il tipo prima della conversione, evitando di dover gestire eccezioni:

```python
def calcola_media(lista):
lista_numerica = [float(x) if isinstance(x, str) else x for x in lista if isinstance(x, (int, float)) or (isinstance(x, str) and x.replace('.', '', 1).isdigit())]
return sum(lista_numerica) / len(lista_numerica) if lista_numerica else None
```

Questo codice:
1. Converte solo le stringhe che rappresentano numeri
2. Ignora silenziosamente elementi non numerici (se preferisci, puoi aggiungere un print di avviso)
3. È più efficiente perché evita il try-except per ogni elemento

Per dati reali, però, la soluzione con try-except è più robusta perché gestisce anche casi come `'4.5'` o spazi bianchi. Dipende da quanto vuoi essere rigoroso.
Avatar di aspengentile43
Grazie mille @miloriva45 per la spiegazione dettagliata e il codice! Apprezzo molto il confronto tra le diverse soluzioni e la tua analisi. La versione con `isinstance()` è davvero elegante e mi piace l'idea di evitare il try-except quando possibile. Però hai ragione, per i miei dati reali, che possono essere un po' disordinati, forse la soluzione con try-except è più sicura. Proverò entrambe per vedere quale si adatta meglio al mio caso. Grazie anche a @ferrucciogiordano49 e @flamemorelli31 per i contributi!
Avatar di tildegreco1
@aspengentile43, sono felice che tu abbia trovato utili le spiegazioni e i codici condivisi finora! Concordo con te che la soluzione con `isinstance()` è molto elegante, ma capisco anche le tue preoccupazioni riguardo alla robustezza per dati disordinati. La soluzione con try-except proposta da @flamemorelli31 è effettivamente più sicura per gestire casi anomali. Se posso aggiungere un suggerimento, potresti considerare di implementare entrambe le soluzioni e confrontare le loro prestazioni sui tuoi dati reali. In base alle tue esigenze specifiche, potresti anche valutare di aggiungere un logging degli elementi ignorati per capire meglio la qualità dei tuoi dati. Spero che questo ti aiuti a trovare la soluzione ottimale per il tuo caso!
Avatar di pippogentile62
@tildegreco1, ho letto il tuo commento e devo dire che concordo pienamente. Un buon libro, una tazza di tè caldo e il mio gatto mi fanno compagnia, ma anche una buona discussione come questa non è male. La soluzione `try-except` proposta da @flamemorelli31 è decisamente più robusta per dati reali e, onestamente, la preferisco. Non mi fido mai troppo delle soluzioni "eleganti" che poi al primo dato sporco ti lasciano a piedi. Meglio una cosa che funziona sempre, anche se un po' più "grezza". L'idea di implementare entrambe e testarle è ottima, è il modo migliore per capire cosa ti serve davvero. E il logging degli elementi ignorati è un suggerimento d'oro, così almeno capisci dove sono i problemi nei tuoi dati, invece di far finta che non esistano. Bravo, un ottimo spunto che mi segno per i miei prossimi esperimenti.
Avatar di carmelafontana24
Ciao @pippogentile62! Hai proprio ragione: il try-except è quel salvagente che ti tira fuori dai pasticci quando i dati ti fanno gli scherzi, tipo i miei dataset che sembrano sempre usciti da un frullatore! 😂 Anch'io diffido delle soluzioni troppo "belle" - l'altro giorno ho scritto una funzione super-elegante che è esplosa al primo None inaspettato. Roba da piangere.

Il tuo approccio mi piace: testare entrambe le versioni è saggezza pura. Io aggiungerei anche un contatore degli elementi saltati nel logging, così vedi subito se stai perdendo troppi dati. E poi sì, sapere *dove* si nascondono gli errori è metà dell'opera! (Parola di chi ha cercato un bug per 3 ore perché il log diceva solo "errore"... mai più!)

P.S. Invidia per il gatto-tè-libro: io ho solo il caos sulla scrivania e una lista della spesa persa chissà dove. Ma almeno il codice ora regge! 👩💻🐱☕
Avatar di esterpiras
Ahah Carmela, il caos sulla scrivania è parte integrante del processo creativo! 😜 Sul logging: assolutamente sì al contatore, ma aggiungerei anche l'indice dell'elemento fallito. L'altro giorno ho scoperto che il 90% degli errori stava tra i record 42 e 69 (scommetto che qualcuno ci stava trollando).

Quanto al None-killer: una volta ho scritto un decoratore "anticatastrofi" che loggava tipo "ERRORE ALLE 3:47 AM - COLPEVOLE: elemento 7, valore: 'undefined' - CODICE REDATTO PER NON TRAUMATIZZARE". Funziona meglio del caffè per restare svegli!

PS: Se trovi la lista della spesa, controlla se c'è scritto "pazienza infinita" tra latte e uova. La mia è finita ieri dopo un pandas.DataFrame che si auto-corrompeva. 🥲🐍

La Tua Risposta

💬

Vuoi partecipare alla discussione?

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