Due tipi di numeri, un solo tipo di verità
I tipi numerici che userai ogni giorno sono int e float, più bool per i valori vero/falso. Bastano per quasi tutta l'aritmetica e la logica di cui ha bisogno un normale programma Python.
In Python i booleani sono un sottotipo degli interi: True è letteralmente 1 e False è letteralmente 0, e questo apre la strada a qualche trucco utile più avanti.
Aritmetica con gli interi
Gli interi in Python non vanno mai in overflow. Sembra un dettaglio finché non scrivi la tua prima funzione fattoriale e ti accorgi che la maggior parte degli altri linguaggi a quel punto sarebbe già passata in silenzio a un numero negativo.
Entrambi producono risposte esatte, per quanto grandi. L'unico limite è la memoria.
Gli operatori aritmetici sono quelli che ti aspetti, più un paio:
Tre cose da memorizzare da questo elenco:
/restituisce sempre un float in Python 3, anche quando entrambi i lati sono interi.10 / 2ti dà5.0, non5. Se vuoi un intero, usa//.//arrotonda verso meno infinito, quindi-7 // 2fa-4, non-3. Insolito, ma coerente.%restituisce il resto, ed è comodo per chiedersi "questo numero è pari?" (n % 2 == 0) e per ricominciare da capo dentro un intervallo fisso.
I float e la loro famosa trappola
I float sono imperfetti per costruzione. Vengono memorizzati in binario, che non può rappresentare esattamente la maggior parte delle frazioni decimali. L'esempio da manuale:
La prima riga stampa 0.30000000000000004. La seconda stampa False. Ogni linguaggio che segue lo standard IEEE 754 (Python, JavaScript, Java, C) si comporta così. Non è un bug di Python.
In pratica questo significa due cose:
- Non confrontare i float con
==. Se ti basta "abbastanza vicino", usamath.isclose(a, b)o controlla seabs(a - b) < some_tolerance. - Per i soldi, usa
decimal.Decimal. Il modulodecimaldella libreria standard offre un'aritmetica decimale esatta, senza sorprese come0.1 + 0.2. È più lento dei float, ed è per questo che non è il comportamento predefinito, ma è la scelta giusta per le valute.
Convertire tra tipi numerici
Python non converte di nascosto un intero in stringa o una stringa in numero. Lo chiedi tu in modo esplicito:
Le conversioni non valide sollevano ValueError:
>>> int("hello")
ValueError: invalid literal for int() with base 10: 'hello'
Il messaggio di errore è diretto e facile da gestire. Pulisci l'input o intercetta l'eccezione.
I booleani, un po' più a fondo
True e False sono i due valori booleani, scritti esattamente così, con l'iniziale maiuscola. La maggior parte dei confronti ne produce uno:
Gli operatori booleani sono and, or e not, scritti come parole inglesi invece che con simboli:
Una sottigliezza utile da conoscere: and e or non restituiscono per forza True o False, ma il valore che ha deciso l'espressione. 0 or "fallback" restituisce "fallback"; 5 and 10 restituisce 10. Questo ti permette di scrivere valori predefiniti brevi come name = user_input or "anonymous", ma è bene saperlo anche nel caso in cui un controllo booleano ti restituisca un tipo inaspettato.
Truthy e falsy
Python tratta molti valori come "quasi veri" o "quasi falsi" quando li usi in un contesto booleano come if o while. I valori falsy sono:
False0,0.0None- I contenitori vuoti:
"",[],{},set(),()
Tutto il resto è truthy. Questo ti permette di scrivere controlli dall'aspetto più naturale:
Leggi if name: come "se name contiene qualcosa". Molto più pulito di if name != "":. Fai solo attenzione con i numeri: if count: tratterà 0 come "salta", che di solito, ma non sempre, è quello che vuoi. Se zero è un valore legittimo, usa invece if count is not None:.
Aritmetica con i booleani
Visto che i booleani sono interi, puoi farci dei calcoli:
È un trucco che torna utile abbastanza spesso da tenerlo a mente. Se vuoi contare quanti elementi di una lista superano un test, somma un generatore che restituisce booleani:
In pratica
- Gli interi non vanno mai in overflow. Usali liberamente.
/restituisce un float; usa//quando vuoi la divisione intera.- Non confrontare i float con
==; confrontali con una tolleranza, oppure usaDecimalper i soldi. - La truthiness rende le condizioni più leggibili, purché ti ricordi che
0e le stringhe vuote sono falsy.
Prossimo argomento: input e print, i due strumenti che trasformano i tuoi script da programmi muti in conversazioni.
Domande frequenti
Che differenza c'è tra int e float in Python?
Un int è un numero intero senza virgola; un float è un numero con la virgola (il punto decimale). Gli interi in Python possono avere qualsiasi dimensione: non c'è overflow. I float seguono le regole standard IEEE 754, il che significa che possono perdere minuscole quantità di precisione nell'aritmetica decimale.
Perché in Python 0.1 + 0.2 non è uguale a 0.3?
Perché i numeri in virgola mobile binari non possono rappresentare esattamente la maggior parte dei decimali. 0.1 + 0.2 dà come risultato 0.30000000000000004. Non è un bug di Python: ogni linguaggio con float IEEE 754 si comporta allo stesso modo. Per calcoli decimali esatti, usa il modulo decimal.
Cosa sono i valori truthy e falsy in Python?
Nei contesti booleani Python tratta molti valori come veri o falsi, anche se non sono letteralmente True o False. Zero, stringhe vuote, liste vuote, dict vuoti e None sono falsy; quasi tutti gli altri valori sono truthy. if my_list: si legge come "se la lista contiene qualcosa".