Contenuti




Python: cheat sheet

Riferimento rapido ai concetti fondamentali


Python: cheat sheet

Questo cheat sheet completo di Python è progettato per essere la tua risorsa di riferimento rapido per la programmazione Python. Che tu sia un principiante che sta imparando le basi o uno sviluppatore esperto che ha bisogno di un promemoria veloce, questa guida copre tutto quello di cui hai bisogno.

In questo articolo
  • Sintassi base: Variabili, operatori, strutture di controllo
  • Strutture dati: Liste, tuple, dizionari, set con operazioni avanzate
  • Funzioni: Definizione, parametri, lambda, decoratori
  • OOP: Classi, ereditarietà, metodi speciali
  • Gestione errori: Try/except, eccezioni personalizzate
  • File I/O: Lettura, scrittura, gestione file
  • Librerie standard: Moduli essenziali con esempi pratici
  • Trucchi avanzati: List comprehension, generatori, context manager

Indice Rapido

  1. Basi e sintassi
  2. Variabili e Tipi di Dati
  3. Operatori
  4. Strutture di Controllo
  5. Strutture Dati
  6. Funzioni
  7. Classi e OOP
  8. Gestione Errori
  9. Gestione file
  10. Moduli e Package
  11. Librerie Standard
  12. Tecniche Avanzate

Basi e sintassi

Commenti

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Commento su singola riga

"""
Commento su
multiple righe
"""

'''
Altro modo per
commenti multiriga
'''
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# Output base
print("Ciao mondo!")
print("Valore:", 42)
print("Nome:", "Mario", "Età:", 30)

# Formattazione avanzata
name = "Alice"
age = 25
print(f"Mi chiamo {name} e ho {age} anni")          # f-strings (Python 3.6+)
print("Mi chiamo {} e ho {} anni".format(name, age))  # format method
print("Mi chiamo %s e ho %d anni" % (name, age))    # % formatting

# Input utente
nome = input("Come ti chiami? ")
età = int(input("Quanti anni hai? "))
prezzo = float(input("Inserisci un prezzo: "))

Indentazione e Blocchi

1
2
3
4
5
6
7
# Python usa l'indentazione per definire i blocchi di codice
if True:
    print("Questo è indentato")
    if True:
        print("Questo è indentato di più")
    print("Di nuovo al primo livello")
print("Nessuna indentazione")

Variabili e Tipi di Dati

Tipi di Dati Primitivi

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Numeri interi
x = 42
y = -17
z = 0

# Numeri decimali (float)
pi = 3.14159
negative = -2.5
scientific = 1.23e-4  # Notazione scientifica

# Stringhe
nome = "Mario"
cognome = 'Rossi'
multiline = """Questa è
una stringa
su più righe"""

# Booleani
vero = True
falso = False

# None (valore nullo)
vuoto = None

# Verifica del tipo
print(type(x))          # <class 'int'>
print(isinstance(x, int))  # True

Conversione di Tipo

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# Conversioni esplicite
numero_str = "123"
numero_int = int(numero_str)     # String to int
numero_float = float(numero_str) # String to float

# Conversioni con controllo errori
try:
    valore = int(input("Inserisci un numero: "))
except ValueError:
    print("Non è un numero valido!")

# Conversioni utili
str(123)        # "123"
int("123")      # 123
float("12.34")  # 12.34
bool(1)         # True
bool(0)         # False
list("hello")   # ['h', 'e', 'l', 'l', 'o']

Operatori

Operatori Aritmetici

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
x, y = 10, 3

# Operatori base
somma = x + y           # 13
differenza = x - y      # 7
prodotto = x * y        # 30
divisione = x / y       # 3.333...
divisione_intera = x // y  # 3
resto = x % y           # 1
potenza = x ** y        # 1000

# Operatori di assegnazione
x += 5    # x = x + 5
x -= 3    # x = x - 3
x *= 2    # x = x * 2
x /= 4    # x = x / 4
x **= 2   # x = x ** 2

Operatori di Confronto

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
x, y = 5, 3

# Confronti base
uguale = x == y         # False
diverso = x != y        # True
maggiore = x > y        # True
minore = x < y          # False
maggiore_uguale = x >= y  # True
minore_uguale = x <= y   # False

# Confronti con stringhe
"apple" < "banana"      # True (ordine alfabetico)
"Hello" == "hello"      # False (case sensitive)

Operatori Logici

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
a, b = True, False

# Operatori logici base
and_result = a and b    # False
or_result = a or b      # True
not_result = not a      # False

# Operatori con valori "truthy" e "falsy"
# Falsy values: False, None, 0, "", [], {}, set()
# Tutto il resto è truthy

result = "hello" and 42   # 42 (ritorna l'ultimo valore truthy)
result = "" or "default"  # "default"
result = None or 0 or "found"  # "found"

Operatori di Membership e Identity

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# Membership operators
lista = [1, 2, 3, 4, 5]
print(3 in lista)       # True
print(6 not in lista)   # True

stringa = "Hello World"
print("World" in stringa)  # True

# Identity operators
x = [1, 2, 3]
y = [1, 2, 3]
z = x

print(x is y)           # False (oggetti diversi)
print(x is z)           # True (stesso oggetto)
print(x == y)           # True (stesso contenuto)

Strutture di Controllo

If, Elif, Else

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# Struttura base
età = 18
if età >= 18:
    print("Maggiorenne")
else:
    print("Minorenne")

# If con elif
voto = 85
if voto >= 90:
    print("Eccellente")
elif voto >= 80:
    print("Buono")
elif voto >= 70:
    print("Sufficiente")
else:
    print("Insufficiente")

# If ternario (conditional expression)
risultato = "Pari" if numero % 2 == 0 else "Dispari"

Loop For

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Iterazione su lista
frutti = ["mela", "banana", "arancia"]
for frutto in frutti:
    print(frutto)

# Iterazione con indice
for i, frutto in enumerate(frutti):
    print(f"{i}: {frutto}")

# Range
for i in range(5):          # 0, 1, 2, 3, 4
    print(i)

for i in range(2, 8):       # 2, 3, 4, 5, 6, 7
    print(i)

for i in range(0, 10, 2):   # 0, 2, 4, 6, 8
    print(i)

# Iterazione su dizionario
persona = {"nome": "Mario", "età": 30, "città": "Roma"}
for chiave in persona:
    print(chiave, persona[chiave])

for chiave, valore in persona.items():
    print(f"{chiave}: {valore}")

Loop While

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# While base
contatore = 0
while contatore < 5:
    print(contatore)
    contatore += 1

# While con condizione complessa
risposta = ""
while risposta.lower() not in ["si", "no"]:
    risposta = input("Vuoi continuare? (si/no): ")

# While True con break
while True:
    comando = input("Inserisci comando (q per uscire): ")
    if comando == "q":
        break
    print(f"Hai inserito: {comando}")

Break, Continue, Pass

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# Break - esce dal loop
for i in range(10):
    if i == 5:
        break
    print(i)  # Stampa 0, 1, 2, 3, 4

# Continue - salta all'iterazione successiva
for i in range(10):
    if i % 2 == 0:
        continue
    print(i)  # Stampa solo numeri dispari

# Pass - placeholder vuoto
for i in range(5):
    if i == 3:
        pass  # TODO: implementare qualcosa qui
    else:
        print(i)

Strutture Dati

Liste

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# Creazione
lista_vuota = []
lista_numeri = [1, 2, 3, 4, 5]
lista_mista = ["hello", 42, True, 3.14]
lista_da_range = list(range(10))

# Accesso e modifica
print(lista_numeri[0])      # Primo elemento: 1
print(lista_numeri[-1])     # Ultimo elemento: 5
lista_numeri[0] = 10        # Modifica primo elemento

# Slicing
print(lista_numeri[1:4])    # [2, 3, 4]
print(lista_numeri[:3])     # [1, 2, 3]
print(lista_numeri[2:])     # [3, 4, 5]
print(lista_numeri[::-1])   # Lista invertita

# Metodi principali
lista_numeri.append(6)              # Aggiunge alla fine
lista_numeri.insert(0, 0)           # Inserisce in posizione
lista_numeri.remove(3)              # Rimuove primo 3 trovato
elemento = lista_numeri.pop()       # Rimuove e restituisce ultimo
elemento = lista_numeri.pop(0)      # Rimuove e restituisce per indice
lista_numeri.sort()                 # Ordina in-place
lista_numeri.reverse()              # Inverte in-place
copia = lista_numeri.copy()         # Crea copia shallow

# Operazioni utili
lunghezza = len(lista_numeri)       # Lunghezza
massimo = max(lista_numeri)         # Valore massimo
minimo = min(lista_numeri)          # Valore minimo
somma = sum(lista_numeri)           # Somma elementi

Tuple

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# Creazione (immutabili)
tupla_vuota = ()
tupla_singola = (42,)  # Virgola necessaria per tupla con un elemento
coordinate = (10, 20)
persona = ("Mario", "Rossi", 30)

# Unpacking
x, y = coordinate
nome, cognome, età = persona

# Tuple con valori di default
def get_nome_età():
    return "Alice", 25

nome, età = get_nome_età()

# Metodi
print(persona.count("Mario"))  # Conta occorrenze
print(persona.index("Rossi"))  # Trova indice

Dizionari

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# Creazione
dizionario_vuoto = {}
persona = {
    "nome": "Mario",
    "cognome": "Rossi",
    "età": 30,
    "città": "Roma"
}

# Creazione alternativa
persona2 = dict(nome="Alice", età=25, città="Milano")

# Accesso
print(persona["nome"])              # "Mario"
print(persona.get("telefono"))      # None (chiave non esistente)
print(persona.get("telefono", "N/A"))  # "N/A" (valore default)

# Modifica
persona["età"] = 31                 # Modifica valore esistente
persona["telefono"] = "123-456789"  # Aggiunge nuova chiave

# Metodi principali
chiavi = persona.keys()             # Tutte le chiavi
valori = persona.values()           # Tutti i valori
elementi = persona.items()          # Coppie (chiave, valore)

# Rimozione
del persona["telefono"]             # Rimuove chiave
età = persona.pop("età", 0)         # Rimuove e restituisce
ultimo = persona.popitem()          # Rimuove ultimo elemento

# Operazioni avanzate
persona.update({"lavoro": "Ingegnere", "stipendio": 50000})
copia = persona.copy()              # Copia shallow

Set

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Creazione
set_vuoto = set()
numeri = {1, 2, 3, 4, 5}
lettere = set("hello")  # {'h', 'e', 'l', 'o'}

# Operazioni
numeri.add(6)                       # Aggiunge elemento
numeri.remove(3)                    # Rimuove elemento (errore se non esiste)
numeri.discard(10)                  # Rimuove elemento (nessun errore)

# Operazioni sui set
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}

unione = set1 | set2                # {1, 2, 3, 4, 5, 6}
intersezione = set1 & set2          # {3, 4}
differenza = set1 - set2            # {1, 2}
diff_simmetrica = set1 ^ set2       # {1, 2, 5, 6}

# Test
print(3 in set1)                    # True
print(set1.issubset(set2))          # False
print(set1.issuperset({1, 2}))      # True

Funzioni

Definizione Base

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# Funzione semplice
def saluta():
    print("Ciao!")

saluta()  # Chiamata

# Funzione con parametri
def saluta_persona(nome):
    print(f"Ciao {nome}!")

saluta_persona("Mario")

# Funzione con valore di ritorno
def somma(a, b):
    return a + b

risultato = somma(5, 3)  # 8

Parametri Avanzati

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Parametri con valori default
def presenta(nome, età=0, città="Non specificata"):
    return f"{nome}, {età} anni, da {città}"

print(presenta("Mario"))                    # Usa valori default
print(presenta("Alice", 25))                # Usa default per città
print(presenta("Bob", 30, "Roma"))          # Tutti i parametri

# Parametri keyword-only
def configura(host, porta=8080, *, debug=False, verbose=False):
    return f"Server: {host}:{porta}, Debug: {debug}, Verbose: {verbose}"

# debug e verbose devono essere chiamati per nome
configura("localhost", debug=True)

# *args e **kwargs
def funzione_flessibile(*args, **kwargs):
    print("Argomenti posizionali:", args)
    print("Argomenti nominali:", kwargs)

funzione_flessibile(1, 2, 3, nome="Mario", età=30)
# Output:
# Argomenti posizionali: (1, 2, 3)
# Argomenti nominali: {'nome': 'Mario', 'età': 30}

Lambda Functions

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# Funzione lambda base
quadrato = lambda x: x ** 2
print(quadrato(5))  # 25

# Lambda con più parametri
somma = lambda a, b: a + b
print(somma(3, 4))  # 7

# Uso con map, filter, sort
numeri = [1, 2, 3, 4, 5]
quadrati = list(map(lambda x: x**2, numeri))  # [1, 4, 9, 16, 25]
pari = list(filter(lambda x: x % 2 == 0, numeri))  # [2, 4]

# Ordinamento con lambda
persone = [("Mario", 30), ("Alice", 25), ("Bob", 35)]
persone.sort(key=lambda persona: persona[1])  # Ordina per età

Decoratori Base

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Decoratore semplice
def log_chiamate(func):
    def wrapper(*args, **kwargs):
        print(f"Chiamando {func.__name__}")
        risultato = func(*args, **kwargs)
        print(f"Finito {func.__name__}")
        return risultato
    return wrapper

@log_chiamate
def saluta(nome):
    print(f"Ciao {nome}!")

saluta("Mario")  # Stamperà anche i log

# Decoratore con parametri
def ripeti(volte):
    def decoratore(func):
        def wrapper(*args, **kwargs):
            for _ in range(volte):
                risultato = func(*args, **kwargs)
            return risultato
        return wrapper
    return decoratore

@ripeti(3)
def di_ciao():
    print("Ciao!")

di_ciao()  # Stampa "Ciao!" 3 volte

Classi e OOP

Classi Base

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# Definizione classe
class Persona:
    # Attributo di classe
    specie = "Homo sapiens"

    def __init__(self, nome, età):
        # Attributi di istanza
        self.nome = nome
        self.età = età

    # Metodo di istanza
    def presenta(self):
        return f"Mi chiamo {self.nome} e ho {self.età} anni"

    # Metodo di classe
    @classmethod
    def da_stringa(cls, stringa_persona):
        nome, età = stringa_persona.split('-')
        return cls(nome, int(età))

    # Metodo statico
    @staticmethod
    def è_adulto(età):
        return età >= 18

# Utilizzo
mario = Persona("Mario", 30)
print(mario.presenta())

# Metodo di classe
alice = Persona.da_stringa("Alice-25")

# Metodo statico
print(Persona.è_adulto(17))  # False

Ereditarietà

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Classe padre
class Animale:
    def __init__(self, nome, specie):
        self.nome = nome
        self.specie = specie

    def verso(self):
        return "Fa un verso"

# Classe figlia
class Cane(Animale):
    def __init__(self, nome, razza):
        super().__init__(nome, "Canis lupus")  # Chiama costruttore padre
        self.razza = razza

    def verso(self):  # Override del metodo padre
        return "Bau bau!"

    def porta_bastone(self):  # Metodo specifico della classe figlia
        return f"{self.nome} porta il bastone"

# Utilizzo
fido = Cane("Fido", "Labrador")
print(fido.verso())  # "Bau bau!"
print(fido.porta_bastone())

Metodi Speciali (Magic Methods)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Punto:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self):  # Per print() e str()
        return f"Punto({self.x}, {self.y})"

    def __repr__(self):  # Per rappresentazione sviluppatore
        return f"Punto(x={self.x}, y={self.y})"

    def __add__(self, altro):  # Per operatore +
        return Punto(self.x + altro.x, self.y + altro.y)

    def __eq__(self, altro):  # Per operatore ==
        return self.x == altro.x and self.y == altro.y

    def __len__(self):  # Per len()
        return int((self.x**2 + self.y**2)**0.5)

# Utilizzo
p1 = Punto(3, 4)
p2 = Punto(1, 2)
print(p1)           # "Punto(3, 4)"
print(p1 + p2)      # "Punto(4, 6)"
print(p1 == p2)     # False
print(len(p1))      # 5

Properties

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Temperatura:
    def __init__(self, celsius=0):
        self._celsius = celsius

    @property
    def celsius(self):
        return self._celsius

    @celsius.setter
    def celsius(self, valore):
        if valore < -273.15:
            raise ValueError("Temperatura sotto zero assoluto!")
        self._celsius = valore

    @property
    def fahrenheit(self):
        return self._celsius * 9/5 + 32

    @fahrenheit.setter
    def fahrenheit(self, valore):
        self.celsius = (valore - 32) * 5/9

# Utilizzo
temp = Temperatura(25)
print(temp.celsius)      # 25
print(temp.fahrenheit)   # 77.0
temp.fahrenheit = 100
print(temp.celsius)      # 37.77...

Gestione Errori

Try, Except, Finally

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# Gestione base
try:
    numero = int(input("Inserisci un numero: "))
    risultato = 10 / numero
    print(f"Risultato: {risultato}")
except ValueError:
    print("Non hai inserito un numero valido!")
except ZeroDivisionError:
    print("Non puoi dividere per zero!")
except Exception as e:
    print(f"Errore imprevisto: {e}")
finally:
    print("Questo viene sempre eseguito")

# Cattura multipla
try:
    # codice rischioso
    pass
except (ValueError, TypeError) as e:
    print(f"Errore di tipo: {e}")

Eccezioni Personalizzate

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# Definizione eccezione personalizzata
class ErroreEtàNegativa(Exception):
    def __init__(self, età):
        self.età = età
        super().__init__(f"L'età non può essere negativa: {età}")

class Persona:
    def __init__(self, nome, età):
        if età < 0:
            raise ErroreEtàNegativa(età)
        self.nome = nome
        self.età = età

# Utilizzo
try:
    persona = Persona("Mario", -5)
except ErroreEtàNegativa as e:
    print(f"Errore: {e}")

Raise e Assert

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Sollevare eccezioni
def dividi(a, b):
    if b == 0:
        raise ValueError("Il divisore non può essere zero")
    return a / b

# Assert per debug
def calcola_radice(numero):
    assert numero >= 0, "Il numero deve essere non negativo"
    return numero ** 0.5

# Context manager per gestione risorse
class FileManager:
    def __init__(self, filename, mode):
        self.filename = filename
        self.mode = mode
        self.file = None

    def __enter__(self):
        self.file = open(self.filename, self.mode)
        return self.file

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.file:
            self.file.close()

# Utilizzo
with FileManager("test.txt", "w") as f:
    f.write("Ciao mondo!")
# Il file viene chiuso automaticamente

Gestione file

Lettura e Scrittura File

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Scrittura file
with open("file.txt", "w", encoding="utf-8") as f:
    f.write("Prima riga\n")
    f.write("Seconda riga\n")

# Lettura completa
with open("file.txt", "r", encoding="utf-8") as f:
    contenuto = f.read()
    print(contenuto)

# Lettura riga per riga
with open("file.txt", "r", encoding="utf-8") as f:
    for riga in f:
        print(riga.strip())  # strip() rimuove \n

# Lettura tutte le righe in lista
with open("file.txt", "r", encoding="utf-8") as f:
    righe = f.readlines()

# Append (aggiunta)
with open("file.txt", "a", encoding="utf-8") as f:
    f.write("Nuova riga\n")

Gestione CSV

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import csv

# Scrittura CSV
dati = [
    ["Nome", "Età", "Città"],
    ["Mario", 30, "Roma"],
    ["Alice", 25, "Milano"],
    ["Bob", 35, "Napoli"]
]

with open("persone.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerows(dati)

# Lettura CSV
with open("persone.csv", "r", encoding="utf-8") as f:
    reader = csv.reader(f)
    for riga in reader:
        print(riga)

# CSV con DictReader/DictWriter
with open("persone.csv", "r", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    for riga in reader:
        print(f"{riga['Nome']} ha {riga['Età']} anni")

JSON

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import json

# Dati Python to JSON
dati = {
    "nome": "Mario",
    "età": 30,
    "città": "Roma",
    "hobby": ["calcio", "lettura", "cucina"]
}

# Scrittura JSON
with open("dati.json", "w", encoding="utf-8") as f:
    json.dump(dati, f, indent=4, ensure_ascii=False)

# Lettura JSON
with open("dati.json", "r", encoding="utf-8") as f:
    dati_caricati = json.load(f)

# JSON da/a stringa
json_string = json.dumps(dati, indent=2)
dati_da_string = json.loads(json_string)

Moduli e Package

Import Base

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# Import intero modulo
import math
print(math.pi)
print(math.sqrt(16))

# Import specifico
from math import pi, sqrt
print(pi)
print(sqrt(16))

# Import con alias
import datetime as dt
oggi = dt.date.today()

from collections import Counter as C
contatore = C("hello")

# Import tutto (sconsigliato)
from math import *

Creare Moduli Personalizzati

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# File: my_module.py
def saluta(nome):
    return f"Ciao {nome}!"

def calcola_area_cerchio(raggio):
    import math
    return math.pi * raggio ** 2

# Variabile del modulo
VERSION = "1.0.0"

# Codice eseguito solo se il file è eseguito direttamente
if __name__ == "__main__":
    print("Questo modulo è stato eseguito direttamente")
    print(saluta("Mondo"))

# File principale: main.py
import my_module

print(my_module.saluta("Mario"))
print(my_module.VERSION)

Package

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Struttura directory:
# my_package/
#   __init__.py
#   math_utils.py
#   string_utils.py

# File: my_package/__init__.py
from .math_utils import somma, prodotto
from .string_utils import capitalizza

__version__ = "1.0.0"
__all__ = ["somma", "prodotto", "capitalizza"]

# File: my_package/math_utils.py
def somma(a, b):
    return a + b

def prodotto(a, b):
    return a * b

# Utilizzo
from my_package import somma, capitalizza
print(somma(3, 4))

Librerie Standard

Datetime

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import datetime as dt

# Data e ora corrente
ora_corrente = dt.datetime.now()
data_corrente = dt.date.today()
ora_corrente_utc = dt.datetime.utcnow()

# Creare date specifiche
compleanno = dt.date(1990, 5, 15)
evento = dt.datetime(2024, 12, 25, 14, 30, 0)

# Operazioni con date
domani = data_corrente + dt.timedelta(days=1)
settimana_prossima = data_corrente + dt.timedelta(weeks=1)
due_ore_fa = ora_corrente - dt.timedelta(hours=2)

# Formattazione
print(ora_corrente.strftime("%d/%m/%Y %H:%M:%S"))
print(data_corrente.strftime("%A %d %B %Y"))

# Parsing da stringa
data_stringa = "2024-03-15 14:30:00"
data_parsed = dt.datetime.strptime(data_stringa, "%Y-%m-%d %H:%M:%S")

Collections

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from collections import Counter, defaultdict, deque, namedtuple

# Counter - conteggio elementi
testo = "hello world"
conteggio = Counter(testo)
print(conteggio)  # Counter({'l': 3, 'o': 2, 'h': 1, ...})
print(conteggio.most_common(3))  # I 3 più comuni

# defaultdict - dizionario con valori default
dd = defaultdict(list)
dd['frutti'].append('mela')
dd['frutti'].append('banana')
print(dd)  # defaultdict(<class 'list'>, {'frutti': ['mela', 'banana']})

# deque - lista ottimizzata per inserimenti/rimozioni agli estremi
queue = deque([1, 2, 3])
queue.appendleft(0)  # Aggiunge all'inizio
queue.append(4)      # Aggiunge alla fine
print(queue.popleft())  # Rimuove dall'inizio

# namedtuple - tupla con campi nominati
Punto = namedtuple('Punto', ['x', 'y'])
p = Punto(3, 4)
print(p.x, p.y)  # 3 4

Itertools

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import itertools

# Combinazioni e permutazioni
lettere = ['A', 'B', 'C']
print(list(itertools.permutations(lettere, 2)))  # Permutazioni
print(list(itertools.combinations(lettere, 2)))  # Combinazioni

# Cycle - ripete infinitamente
colori = itertools.cycle(['rosso', 'verde', 'blu'])
for i, colore in enumerate(colori):
    if i >= 6:
        break
    print(colore)

# Chain - concatena iterabili
lista1 = [1, 2, 3]
lista2 = [4, 5, 6]
concatenata = list(itertools.chain(lista1, lista2))

# Groupby - raggruppa elementi consecutivi
dati = [1, 1, 2, 2, 2, 3, 1, 1]
for chiave, gruppo in itertools.groupby(dati):
    print(f"{chiave}: {list(gruppo)}")

Random

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import random

# Numeri casuali
print(random.random())          # Float tra 0 e 1
print(random.randint(1, 10))    # Int tra 1 e 10 (inclusivi)
print(random.uniform(1.5, 5.5)) # Float tra 1.5 e 5.5

# Scelte casuali
colori = ['rosso', 'verde', 'blu', 'giallo']
print(random.choice(colori))            # Un elemento casuale
print(random.choices(colori, k=3))      # 3 elementi (con ripetizione)
print(random.sample(colori, k=2))       # 2 elementi (senza ripetizione)

# Mescolare lista
carte = list(range(1, 53))
random.shuffle(carte)

# Seed per riproducibilità
random.seed(42)
print(random.random())  # Sempre lo stesso risultato con seed 42

Os e Path

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import os
from pathlib import Path

# Informazioni sistema
print(os.getcwd())          # Directory corrente
print(os.listdir('.'))      # File nella directory corrente
print(os.environ['HOME'])   # Variabile d'ambiente

# Operazioni path (modo tradizionale)
path = os.path.join('home', 'user', 'documents', 'file.txt')
print(os.path.exists(path))
print(os.path.dirname(path))
print(os.path.basename(path))

# Pathlib (modo moderno, consigliato)
p = Path('home') / 'user' / 'documents' / 'file.txt'
print(p.exists())
print(p.parent)     # Directory genitore
print(p.name)       # Nome file
print(p.suffix)     # Estensione
print(p.stem)       # Nome senza estensione

# Creazione directory
Path('nuova_dir').mkdir(exist_ok=True)
Path('nested/deep/dir').mkdir(parents=True, exist_ok=True)

# Iterazione file
for file_path in Path('.').glob('*.py'):
    print(file_path)

Tecniche Avanzate

List Comprehensions

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# Base
numeri = [1, 2, 3, 4, 5]
quadrati = [x**2 for x in numeri]

# Con condizione
pari = [x for x in numeri if x % 2 == 0]

# Con if-else
segni = ['positivo' if x > 0 else 'negativo' for x in [-1, 2, -3, 4]]

# Nested loops
matrice = [[i*j for j in range(1, 4)] for i in range(1, 4)]

# Dict comprehension
quadrati_dict = {x: x**2 for x in range(1, 6)}

# Set comprehension
lettere_uniche = {char.lower() for char in "Hello World" if char.isalpha()}

Generatori

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Generator function
def fibonacci(n):
    a, b = 0, 1
    for _ in range(n):
        yield a
        a, b = b, a + b

# Utilizzo
for numero in fibonacci(10):
    print(numero)

# Generator expression
quadrati = (x**2 for x in range(10))
print(sum(quadrati))

# Generator infinito
def numeri_pari():
    n = 0
    while True:
        yield n
        n += 2

# Utilizzo con itertools.islice per limitare
import itertools
primi_10_pari = list(itertools.islice(numeri_pari(), 10))

Context Managers

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# Context manager personalizzato
class TimerContext:
    def __enter__(self):
        import time
        self.start = time.time()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        import time
        elapsed = time.time() - self.start
        print(f"Tempo trascorso: {elapsed:.2f} secondi")

# Utilizzo
with TimerContext():
    import time
    time.sleep(1)  # Simula operazione lenta

# Context manager con contextlib
from contextlib import contextmanager

@contextmanager
def database_transaction():
    print("Inizio transazione")
    try:
        yield "connection"
        print("Commit transazione")
    except Exception:
        print("Rollback transazione")
        raise
    finally:
        print("Chiusura connessione")

# Utilizzo
with database_transaction() as conn:
    print(f"Usando {conn}")
    # raise Exception("Errore!")  # Decommentare per testare rollback

Decoratori Avanzati

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import functools
import time

# Decoratore con cache
@functools.lru_cache(maxsize=128)
def fibonacci_cached(n):
    if n <= 1:
        return n
    return fibonacci_cached(n-1) + fibonacci_cached(n-2)

# Decoratore per misurare tempo
def misura_tempo(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        risultato = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} ha impiegato {end-start:.4f} secondi")
        return risultato
    return wrapper

@misura_tempo
def operazione_lenta():
    time.sleep(0.1)
    return "Completato"

# Decoratore con parametri
def retry(max_tentativi=3, delay=1):
    def decoratore(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            for tentativo in range(max_tentativi):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    if tentativo == max_tentativi - 1:
                        raise
                    print(f"Tentativo {tentativo + 1} fallito: {e}")
                    time.sleep(delay)
        return wrapper
    return decoratore

@retry(max_tentativi=3, delay=0.5)
def operazione_instabile():
    import random
    if random.random() < 0.7:
        raise Exception("Operazione fallita")
    return "Successo!"

Type Hints

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from typing import List, Dict, Optional, Union, Callable, Any

# Type hints base
def saluta(nome: str) -> str:
    return f"Ciao {nome}!"

# Tipi complessi
def processa_numeri(numeri: List[int]) -> Dict[str, float]:
    return {
        'media': sum(numeri) / len(numeri),
        'massimo': max(numeri),
        'minimo': min(numeri)
    }

# Optional (può essere None)
def trova_persona(id: int) -> Optional[Dict[str, str]]:
    # Simulazione ricerca
    if id == 1:
        return {"nome": "Mario", "cognome": "Rossi"}
    return None

# Union (più tipi possibili)
def converti_a_stringa(valore: Union[int, float, str]) -> str:
    return str(valore)

# Callable (funzioni come parametri)
def applica_operazione(numeri: List[int], operazione: Callable[[int], int]) -> List[int]:
    return [operazione(n) for n in numeri]

# Uso con lambda
risultato = applica_operazione([1, 2, 3], lambda x: x * 2)

# Classi con type hints
class Persona:
    def __init__(self, nome: str, età: int) -> None:
        self.nome = nome
        self.età = età

    def è_maggiorenne(self) -> bool:
        return self.età >= 18

Conclusioni

Risorse Utili