# Operatori Python: presentazione e spiegazione

Gli operatori Python vi aiutano a lavorare con i valori (operandi), a modificarli o a collegarli tra loro. Possono essere logici o aritmetici.

## Cosa sono gli operatori Python e come funzionano?

Un operatore è un **carattere per un’operazione**, solitamente utilizzato per collegare diversi operandi. Di solito, viene creato un nuovo valore. L’applicazione di un operatore a un singolo operando lo modifica.

Probabilmente l’esempio più semplice di operatori Python è il collegamento di due numeri mediante l’**operatore di addizione**, cioè un segno più tra i numeri. Python valuta l’espressione e restituisce il valore corrispondente:

```none
1 + 1
```

Una peculiarità di Python è che parole brevi come “and”, “or”, “is”, “not” o “in” vengono utilizzate come operatori in aggiunta ai simboli. La **combinazione di operatori e operandi** dà luogo a un’espressione:

```none
1 + 1 == 2
```

### Quali tipi di operatori Python esistono?

Python conosce diverse classi di operatori. **Agiscono su diversi tipi di operandi** e restituiscono risultati di un certo tipo. Di seguito vi riportiamo i diversi tipi di operatori Python in sintesi:

<table>
  <thead>
    <tr>
      <th>Classi di operatori Python</th>
      <th>Spiegazione</th>
      <th>Operandi</th>
      <th>Risultato</th>
      <th>Operatori in sintesi</th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Operatori aritmetici</td>
      <td>Combinazione di due numeri per formarne uno nuovo</td>
      <td>Numeri</td>
      <td>Numero</td>
      <td>+, -, \*, /, //, %, \*\*, @</td>
      <td></td>
    </tr>
    <tr>
      <td>Operatori di confronto</td>
      <td>Confronto tra due espressioni</td>
      <td>Espressioni</td>
      <td>Booleano</td>
      <td>&lt;, &gt;, ==, !=, &lt;=, &gt;=</td>
      <td></td>
    </tr>
    <tr>
      <td>Operatori logici</td>
      <td>Combinazione di espressioni in un contesto booleano</td>
      <td>Espressioni</td>
      <td>Ultima espressione valutata / Booleano</td>
      <td>and, or, not</td>
      <td></td>
    </tr>
    <tr>
      <td>Operatori binari</td>
      <td>Manipolazione di interi come sequenze binarie</td>
      <td>Numeri</td>
      <td>Numero</td>
      <td>&lt;&lt;, &gt;&gt;, &amp;,</td>
      <td>, ^, ~</td>
    </tr>
    <tr>
      <td>Operatori di assegnazione</td>
      <td>Assegnazione di un valore a un nome</td>
      <td>Valore L, valore R</td>
      <td>- / Espressione valutata</td>
      <td>=, :=, +=, -=, \*=, ecc.</td>
      <td></td>
    </tr>
    <tr>
      <td>Operatori di identità</td>
      <td>Determinazione di due nomi se si riferiscono allo stesso oggetto</td>
      <td>Oggetti</td>
      <td>Booleano</td>
      <td>is, is not</td>
      <td></td>
    </tr>
    <tr>
      <td>Operatori condizionali</td>
      <td>Restituzione di uno dei due valori a seconda di una condizione</td>
      <td>Espressione, condizione, alternativa</td>
      <td>Espressione / Alternativa</td>
      <td>... if ... else ...</td>
      <td></td>
    </tr>
    <tr>
      <td>Operatori di set</td>
      <td>Collegamento di due set / Confronto tra set</td>
      <td>Set</td>
      <td>Set / Booleano</td>
      <td>&amp;,</td>
      <td>, ^, -, &lt;, &gt;, &lt;=, &gt;=</td>
    </tr>
    <tr>
      <td>Operatori di appartenenza</td>
      <td>Verifica di un’iterabile se contiene un particolare oggetto</td>
      <td>Oggetto, Iterabile</td>
      <td>Booleano</td>
      <td>in, not in</td>
      <td></td>
    </tr>
    <tr>
      <td>Operatore di concatenazione</td>
      <td>Concatenazione di sequenze</td>
      <td>Stringhe / Liste / Tuple</td>
      <td>Stringa / Lista / Tupla</td>
      <td>+</td>
      <td></td>
    </tr>
    <tr>
      <td>Operatori di indice e di fetta</td>
      <td>Restituzione di uno o più elementi di un iterabile</td>
      <td>Iterabile, indice / Fetta</td>
      <td>Stringa / Lista / Tupla</td>
      <td>\[\], \[::\]</td>
      <td></td>
    </tr>
  </tbody>
</table>

Oltre al tipo di operandi e al valore di ritorno, gli operatori sono classificati in base alla loro “arietà”. Il termine esprime **il numero di operandi che un operatore collega**. Nella maggior parte dei casi si utilizzano operatori “binari” con due operandi. Inoltre, esistono alcuni operatori “unari” con un solo operando e un operatore “ternario” che collega tre operandi:

<table>
  <thead>
    <tr>
      <th>Arietà degli operatori</th>
      <th>Numero di operandi</th>
      <th>Esempio</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Unario</td>
      <td>Un operando</td>
      <td>not single\_value</td>
    </tr>
    <tr>
      <td>Binario</td>
      <td>Due operandi</td>
      <td>left\_operand + right\_operand</td>
    </tr>
    <tr>
      <td>Ternario</td>
      <td>Tre operandi</td>
      <td>some\_value if condition else other\_value</td>
    </tr>
  </tbody>
</table>

### Osservare la precedenza degli operatori

Fondamentale per l’uso degli operatori Python è anche la comprensione della precedenza degli operatori. Come promemoria, l’espressione 3 \* 8 + 2 viene interpretata come (3 \* 8) + 2 e non come 3 \* (8 + 2). Come per il più e il segno per, esistono regole di precedenza per tutti gli operatori Python. Di seguito un esempio di espressione con gli operatori logici “and”, “or” e “not”:

```none
if is_user and is_user_logged_in or is_admin and not login_blocked:
    ...
```

Senza conoscere le regole di precedenza degli operatori Python coinvolti, è impossibile decidere come i singoli termini debbano stare insieme. Se in un’espressione vengono utilizzati più operatori, la situazione si complica rapidamente. In generale, è meglio **non fare affidamento su una perfetta comprensione delle regole implicite**. Si utilizzano, invece, parentesi esplicite per chiarire l’appartenenza dei termini di un’espressione:

```none
if (is_user and is_user_logged_in) or (is_admin and not login_blocked):
    ...
```

Per un confronto, di seguito **gli stessi termini raggruppati in modo diverso**, in cui l’enunciato delle due espressioni è diverso:

```none
if (is_user and is_user_logged_in or is_admin) and not login_blocked:
    ...
```

### Operatori sovraccaricati, metodi Dunder e funzioni dell’operatore in Python

Alcuni operatori Python sono utilizzati **per più di un’operazione**. Un esempio importante è il segno più, che agisce come operatore di addizione per i numeri e allo stesso tempo come operatore di concatenazione per concatenare sequenze come stringhe e liste. Sommiamo due numeri con l’operatore di addizione:

```none
8 + 3 == 11
```

Con lo stesso operatore concateniamo **due stringhe**:

```none
"Walter" + "White" == "WalterWhite"
```

Con l’operatore più concateniamo anche delle **liste**:

```none
['Jack', 'Jim'] + ['John'] == ['Jack', 'Jim', 'John']
```

Il molteplice uso del segno più come operatore riflette un concetto comune in informatica. Si parla di “**operatori sovraccaricati**” quando uno stesso operatore esegue operazioni diverse a seconda del tipo di dati degli operandi.

Come funzionano gli operatori sovraccaricati in Python? Dietro le quinte, un operatore e i suoi operandi vengono interpretati come una **chiamata a una funzione corrispondente**. In particolare, viene richiamato il cosiddetto metodo Dunder del primo operando, che riceve gli altri operandi come argomenti. “Dunder” sta per “double underscore”, quindi “doppio trattino basso”. Pertanto, l’operatore più corrisponde al metodo Dunder *\_\_add\_\_()*. Gli oggetti che implementano un metodo *\_\_add\_\_()* possono essere collegati con l’operatore più. Spetta all’oggetto stesso stabilire cosa costituisce esattamente il collegamento.

Oltre ai metodi Dunder, il [modulo operator](https://docs.python.org/3/library/operator.html "operator: operatori standard come funzioni - Documentazione in inglese di Python 3.10.4") contiene **funzioni che incapsulano le funzionalità degli operatori Python**. Per esempio, “operator.add(a, b)” richiama il metodo Dunder *a.\_\_add\_\_(b)*, che è equivalente all’espressione *a + b*. Nel resto dell’articolo elenchiamo la funzione dell’operatore per ogni operatore, se prevista. Il nome della funzione dell’operatore equivale al nome del metodo Dunder corrispondente. Utilizzatelo come riferimento per implementare la funzionalità dell’operatore:

<table>
  <thead>
    <tr>
      <th>Operatore Python</th>
      <th>Funzione dell’operatore</th>
      <th>Metodo Dunder</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>a + b</td>
      <td>operator.add(a, b)</td>
      <td>a.\_\_add\_\_(b)</td>
    </tr>
  </tbody>
</table>

Gli operatori utilizzano la cosiddetta **notazione infissa**, che usa l’operatore tra gli operandi. Al contrario, lo stile funzionale utilizza la notazione prefissa. Entrambe le notazioni sono equivalenti:

<table>
  <thead>
    <tr>
      <th>Notazione</th>
      <th>Uso</th>
      <th>Esempio</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Infissa</td>
      <td>Operatori</td>
      <td>a + b</td>
    </tr>
    <tr>
      <td>Prefissa</td>
      <td>Funzioni</td>
      <td>+ a b / add(a, b)</td>
    </tr>
  </tbody>
</table>

Prendiamo in considerazione un esempio. **Definiamo due numeri e li sommiamo** con l’operatore, la sua funzione e il metodo Dunder corrispondente:

```none
import operator
a = 42
b = 69
assert a + b == operator.add(a, b) == a.__add__(b)
```

Anche espressioni più complesse possono essere scritte con le funzioni dell’operatore. Di seguito la combinazione degli operatori di addizione e uguaglianza di Python nella notazione prefissa:

```none
import operator
assert 'Py' + 'thon' == 'Python'
assert operator.eq(operator.add('Py', 'thon'), 'Python')
```

## Gli operatori Python in sintesi

Ora esamineremo **undici diverse classi di operatori Python**.

### Operatori aritmetici

Gli **operatori aritmetici in Python operano sui numeri**, creando un nuovo numero. A eccezione degli operatori unari più e meno, sono tutti operatori binari. Qui un riepilogo:

<table>
  <thead>
    <tr>
      <th>Operatore Python</th>
      <th>Significato</th>
      <th>Funzione dell’operatore</th>
      <th>Esempio</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>+</td>
      <td>Addizione / Più unario</td>
      <td>add(a, b) / pos(a)</td>
      <td>5 + 3 == 8 / +8 == 4 + 4</td>
    </tr>
    <tr>
      <td>-</td>
      <td>Sottrazione / Meno unario</td>
      <td>sub(a, b) / neg(a)</td>
      <td>7 - 2 == 5 / -4 == 2 - 6</td>
    </tr>
    <tr>
      <td>\*</td>
      <td>Moltiplicazione</td>
      <td>mul(a, b)</td>
      <td>2 \* 3 == 6</td>
    </tr>
    <tr>
      <td>/</td>
      <td>Divisione “pura”</td>
      <td>truediv(a, b)</td>
      <td>8 / 2 == 4.0, 7 / 2 == 3.5</td>
    </tr>
    <tr>
      <td>//</td>
      <td>Divisione di un intero del numero intero immediatamente inferiore</td>
      <td>floordiv(a, b)</td>
      <td>8 // 2 == 4, 7 // 2 == 3</td>
    </tr>
    <tr>
      <td>%</td>
      <td>Modulo: quantità rimanente della divisione intera</td>
      <td>mod(a, b)</td>
      <td>8 % 2 == 0, 7 % 2 == 1</td>
    </tr>
    <tr>
      <td>\*\*</td>
      <td>Esponenziazione</td>
      <td>pow(a, b)</td>
      <td>2 \*\* 3 == 8, 10 \*\* -1 == 0.1</td>
    </tr>
    <tr>
      <td>@</td>
      <td>Moltiplicazione di matrici</td>
      <td>matmul(a, b)</td>
      <td>–</td>
    </tr>
  </tbody>
</table>

L’**operazione modulo** viene utilizzata per impostazione predefinita per determinare se un numero è pari. Questo perché un numero pari diviso per due dà resto zero. Definiamo una funzione Python corrispondente con l’operatore modulo:

```none
def is_even(number):
    return number % 2 == 0
# test
assert is_even(8) and not is_even(7)
```

La **moltiplicazione delle matrici** richiede l’uso di un pacchetto come NumPy.

### Operatori di confronto Python

Gli operatori di confronto in Python forniscono una dichiarazione su **come due elementi possono essere ordinati tra loro**. Forniscono un risultato booleano e sono utilizzati in particolare per gli algoritmi di ordinamento:

<table>
  <thead>
    <tr>
      <th>Operatore Python</th>
      <th>Significato</th>
      <th>Funzione dell’operatore</th>
      <th>Esempio</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>&lt;</td>
      <td>Minore di</td>
      <td>lt(a, b)</td>
      <td>3 &lt; 1, 'a' &lt; 'z'</td>
    </tr>
    <tr>
      <td>&gt;</td>
      <td>Maggiore di</td>
      <td>gt(a, b)</td>
      <td>4 &gt; 2, 'z' &gt; 'a'</td>
    </tr>
    <tr>
      <td>==</td>
      <td>Uguale</td>
      <td>eq(a, b)</td>
      <td>'a' == 'a'</td>
    </tr>
    <tr>
      <td>!=</td>
      <td>Disuguale</td>
      <td>ne(a, b)</td>
      <td>1 != 2, 'Jim' != 'Jack'</td>
    </tr>
    <tr>
      <td>&lt;=</td>
      <td>Minore o uguale</td>
      <td>le(a, b)</td>
      <td>9 &lt;= 10, 10 &lt;= 10</td>
    </tr>
    <tr>
      <td>&gt;=</td>
      <td>Maggiore o uguale</td>
      <td>ge(a, b)</td>
      <td>11 &gt;= 10, 10 &gt;= 10</td>
    </tr>
  </tbody>
</table>

### Operatori logici

Gli operatori logici and e or in Python **collegano diversi operandi secondo la logica booleana**. Di conseguenza, entrambi gli operatori restituiscono l’ultimo oggetto valutato. L’operatore logico not in Python interpreta un oggetto nel contesto booleano e nega il suo valore di verità:

<table>
  <thead>
    <tr>
      <th>Operatore Python</th>
      <th>Significato</th>
      <th>Funzione dell’operatore</th>
      <th>Esempio</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>and</td>
      <td>E logica</td>
      <td>Nessun equivalente diretto</td>
      <td>True and False == False, 'name' and ... == ...</td>
    </tr>
    <tr>
      <td>or</td>
      <td>O logico</td>
      <td>Nessun equivalente diretto</td>
      <td>False or True == True, a = '' or 'Default'; assert a == 'Default'</td>
    </tr>
    <tr>
      <td>not</td>
      <td>Negazione</td>
      <td>not\_(a)</td>
      <td>not True == False</td>
    </tr>
  </tbody>
</table>

È utile illustrare l’**effetto delle operazioni logiche** con le tabelle di verità. Qui viene mostrato il metodo logico AND:

<table>
  <tbody>
    <tr>
      <td><strong>and</strong></td>
      <td><strong>True</strong></td>
      <td><strong>False</strong></td>
    </tr>
    <tr>
      <td>True</td>
      <td>True</td>
      <td>False</td>
    </tr>
    <tr>
      <td>False</td>
      <td>False</td>
      <td>False</td>
    </tr>
  </tbody>
</table>

Così come l’OR logico:

<table>
  <tbody>
    <tr>
      <td><strong>or</strong></td>
      <td><strong>True</strong></td>
      <td><strong>False</strong></td>
    </tr>
    <tr>
      <td>True</td>
      <td>True</td>
      <td>True</td>
    </tr>
    <tr>
      <td>False</td>
      <td>True</td>
      <td>False</td>
    </tr>
  </tbody>
</table>

Gli operandi degli operatori booleani in Python non sono limitati alle variabili booleane. Piuttosto, qualsiasi oggetto Python può essere interpretato in un contesto booleano. I **seguenti oggetti hanno una valutazione falsa nel contesto booleano** e sono quindi chiamati “falsy”:

<table>
  <thead>
    <tr>
      <th>Oggetto</th>
      <th>Spiegazione</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>False, None</td>
      <td>Costanti che sono false per definizione</td>
    </tr>
    <tr>
      <td>0, 0.0, Decimal(0), Fraction(0, 1), etc.</td>
      <td>Numero che rappresenta lo zero</td>
    </tr>
    <tr>
      <td>‘‘, (), \[\], {}, set(), range(0), etc.</td>
      <td>Sequenza o insieme vuoti</td>
    </tr>
  </tbody>
</table>

### Operatori binari

Gli operatori binari in Python **operano sui numeri interi, che vengono interpretati come sequenze di bit**. A eccezione dell’operatore NOT, sono tutti operatori binari:

<table>
  <tbody>
    <tr>
      <td><strong>Operatore Python</strong></td>
      <td><strong>Significato</strong></td>
      <td><strong>Funzione dell’operatore</strong></td>
      <td><strong>Esempio</strong></td>
    </tr>
    <tr>
      <td>&lt;&lt;</td>
      <td>Spostamento a sinistra della sequenza di bit</td>
      <td>lshift(a, b)</td>
      <td>5 &lt;&lt; 3 == 5 \* 2 \*\* 3</td>
    </tr>
    <tr>
      <td>&gt;&gt;</td>
      <td>Spostamento a destra della sequenza di bit</td>
      <td>rshift(a, b)</td>
      <td>1 &gt;&gt; 1 == 0, 8 &gt;&gt; 1 == 4</td>
    </tr>
    <tr>
      <td>&amp;</td>
      <td>Collegamento di due sequenze di bit tramite AND</td>
      <td>and\_(a, b)</td>
      <td>``</td> </tr> <tr> <td>|</td> <td>Collegamento di due sequenze di bit tramite OR</td> <td>or\_(a, b)</td> <td>``</td> </tr> <tr> <td>^</td> <td>Collegamento di due sequenze di bit tramite XOR</td> <td>xor(a, b)</td> <td>``</td> </tr> <tr> <td>~</td> <td>Inversione della sequenza di bit con NOT</td> <td>invert(a)</td> <td>``</td>
    </tr>
  </tbody>
</table>

Gli operatori binari sono **adatti a operazioni matematiche ottimizzate**. Ad esempio, lo spostamento a sinistra corrisponde a una moltiplicazione per una potenza di due:

<table>
  <tbody>
    <tr>
      <td><strong>Espressione</strong></td>
      <td><strong>23 = 8</strong></td>
      <td><strong>22 = 4</strong></td>
      <td><strong>21 = 2</strong></td>
      <td><strong>20 = 1</strong></td>
      <td><strong>Decimale</strong></td>
    </tr>
    <tr>
      <td>b = 6</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>0</td>
      <td>6</td>
    </tr>
    <tr>
      <td>b &lt;&lt; 1</td>
      <td>1</td>
      <td>1</td>
      <td>0</td>
      <td>0</td>
      <td>12</td>
    </tr>
    <tr>
      <td>b &gt;&gt; 1</td>
      <td>0</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>3</td>
    </tr>
  </tbody>
</table>

Per illustrare le operazioni binarie AND, OR e NOT, costruiamo una **tabella dei singoli bit**. Le operazioni vengono applicate a un numero in rappresentazione binaria grazie a una maschera di bit:

<table>
  <tbody>
    <tr>
      <td><strong>Espressione</strong></td>
      <td><strong>23 = 8</strong></td>
      <td><strong>22 = 4</strong></td>
      <td><strong>21 = 2</strong></td>
      <td><strong>20 = 1</strong></td>
      <td><strong>Decimale</strong></td>
    </tr>
    <tr>
      <td>bits = 6</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>0</td>
      <td>6</td>
    </tr>
    <tr>
      <td>mask = 5</td>
      <td>0</td>
      <td>1</td>
      <td>0</td>
      <td>1</td>
      <td>5</td>
    </tr>
    <tr>
      <td>bits &amp; mask</td>
      <td>0</td>
      <td>1</td>
      <td>0</td>
      <td>0</td>
      <td>4</td>
    </tr>
    <tr>
      <td>bits | mask</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>7</td>
    </tr>
    <tr>
      <td>bits ^ mask</td>
      <td>0</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>3</td>
    </tr>
  </tbody>
</table>

L’**operatore binario NOT in Python inverte una sequenza di bit**. Ogni 1 diventa uno 0 e viceversa. Inoltre, il segno del numero è invertito:

<table>
  <tbody>
    <tr>
      <td><strong>Espressione</strong></td>
      <td><strong>23 = 8</strong></td>
      <td><strong>22 = 4</strong></td>
      <td><strong>21 = 2</strong></td>
      <td><strong>20 = 1</strong></td>
      <td><strong>Decimale</strong></td>
    </tr>
    <tr>
      <td>b = 6</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>0</td>
      <td>6</td>
    </tr>
    <tr>
      <td>~ b</td>
      <td>1</td>
      <td>0</td>
      <td>0</td>
      <td>1</td>
      <td>-7</td>
    </tr>
  </tbody>
</table>

### Operatori di assegnazione

Le assegnazioni sono tra le istruzioni di base della maggior parte dei linguaggi di programmazione. Gli operatori di assegnazione in Python **legano un valore a un nome di variabile**. Oltre all’istruzione di assegnazione, esiste il più recente operatore “tricheco”, che consente l’assegnazione all’interno di un’espressione. Esiste anche una serie di istruzioni di assegnazione estese che combinano un’assegnazione con un’altra operazione:

<table>
  <thead>
    <tr>
      <th>Operatore Python</th>
      <th>Significato</th>
      <th>Funzione dell’operatore</th>
      <th>Esempio</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>=</td>
      <td>Istruzione di assegnazione</td>
      <td>Nessun equivalente diretto</td>
      <td>name = 'Walther'</td>
    </tr>
    <tr>
      <td>:=</td>
      <td>Espressione di assegnazione (operatore “tricheco”)</td>
      <td>Nessun equivalente diretto</td>
      <td>\[ half for x in range(10) if (half := x / 2) &lt; 5 \]</td>
    </tr>
    <tr>
      <td>+=</td>
      <td>Assegnazione di addizione avanzata</td>
      <td>iadd(a, b)</td>
      <td>x = 1; x += 4; assert x == 5</td>
    </tr>
  </tbody>
</table>

Python conosce operatori di assegnazione avanzati per le operazioni aritmetiche e binarie. Non li elenchiamo singolarmente, ma mostriamo solo lo schema generale utilizzando **l’esempio dell’assegnazione di concatenazione avanzata**. Innanzitutto, viene mostrato un codice che aggiunge un’altra parte a una stringa esistente:

```none
name = 'Walther'
name = name + 'White'
assert name == 'WaltherWhite'
```

Un esempio equivalente con l’operatore di concatenazione avanzato “+=” in Python, in cui si ottiene lo stesso risultato, ma il codice è più stringato e più esplicativo:

```none
name  = 'Walther'
name += 'White'
assert name == 'WaltherWhite'
```

### Operatori di identità

L’operatore is in Python verifica **se due variabili si riferiscono allo stesso oggetto in memoria**. L’identità dell’oggetto è in contrasto con la sua uguaglianza, che viene verificata dall’operatore di confronto Python “==”. L’operatore “is” in Python corrisponde all’incirca all’operatore di uguaglianza rigorosa “===” di JavaScript. Python conosce anche un test d’identità negata con l’operatore “is not”:

<table>
  <thead>
    <tr>
      <th>Operatore Python</th>
      <th>Significato</th>
      <th>Funzione dell’operatore</th>
      <th>Esempio</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>is</td>
      <td>Test d’identità</td>
      <td>is\_(a, b)</td>
      <td>a = 42; b = a; assert a is b</td>
    </tr>
    <tr>
      <td>is not</td>
      <td>Test d’identità negata</td>
      <td>is\_not(a, b)</td>
      <td>assert \[42\] is not \[42\]</td>
    </tr>
  </tbody>
</table>

Vediamo alcuni esempi. Creiamo un riferimento a un oggetto in memoria. In seguito, creeremo un altro riferimento come alias. Se **entrambe le variabili puntano allo stesso oggetto in memoria**, l’operatore is restituisce “True”:

```none
# assign value to name
a = [42]
# reference existing object
b = a
# if this holds
assert a is b
# so will this
assert a == b
```

Qui creiamo due **riferimenti a oggetti indipendenti in memoria**. Malgrado siano gli stessi, gli oggetti rimangono comunque distinti. Di conseguenza, l’operatore is restituisce “False”:

```none
# assign the same value to different names
a = [42]
b = [42]
# `a`, `b` are two different objects
assert a is not b
# that contain the same value
assert a == b
```

### Operatore condizionale

L’operatore condizionale in Python è un altro uso delle parole chiave if-else. Viene spesso utilizzato per **distinguere tra due possibili valori nelle assegnazioni**. Poiché questo operatore combina una condizione e due espressioni, è noto anche come operatore ternario.

<table>
  <thead>
    <tr>
      <th>Operatore Python</th>
      <th>Significato</th>
      <th>Funzione dell’operatore</th>
      <th>Esempio</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>... if ... else ...</td>
      <td>Espressione condizionale</td>
      <td>Nessun equivalente diretto</td>
      <td>name = 'Jim' if age == 42 else 'Jack'</td>
    </tr>
  </tbody>
</table>

Vediamo prima un esempio utilizzando l’[istruzione if-else in Python](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/if-else-in-python/). Il codice seguente imposta Celsius o Fahrenheit come **unità di misura della temperatura**, a seconda del sistema di misura selezionato:

```none
if system == 'metric':
    unit = 'C'
else:
    unit = 'F'
```

**Utilizzando l’operatore condizionale**, il codice può essere semplificato in un singolo assegnamento:

```none
unit = 'C' if system == 'metric' else 'F'
```

### Operatori di set in Python

Oltre a stringhe, tuple, liste e dizionari, Python supporta per impostazione predefinita i **set come tipo di dati composito**. Gli operatori sovraccaricati sono definiti per le consuete operazioni sui set:

<table>
  <thead>
    <tr>
      <th>Operatore Python</th>
      <th>Significato</th>
      <th>Funzione dell’operatore</th>
      <th>Esempio</th>
      <th></th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>&amp;</td>
      <td>Creazione dell’unione di due set</td>
      <td>and\_(a, b)</td>
      <td>{'a', 'b'} &amp; {'a', 'c'} == {'a'}</td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td></td>
      <td></td>
      <td>Creazione dell’intersezione di due set</td>
      <td>or\_(a, b)</td>
      <td>{'a', 'b'}</td>
      <td>{'a', 'c'} == {'a', 'c', 'b'}</td>
    </tr>
    <tr>
      <td>^</td>
      <td>Creazione della differenza simmetrica di due set</td>
      <td>xor(a, b)</td>
      <td>{'a', 'b'} ^ {'a', 'c'} == {'c', 'b'}</td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>-</td>
      <td>Creazione della differenza di due set</td>
      <td>sub(a, b)</td>
      <td>{'a', 'b'} - {'a'} == {'b'}</td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>&gt;</td>
      <td>Verifica se un insieme è un vero superset</td>
      <td>gt(a, b)</td>
      <td>assert {'a', 'b'} &gt; {'a'}</td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>&gt;=</td>
      <td>Verifica se un insieme è un superset</td>
      <td>ge(a, b)</td>
      <td>assert {'a'} &gt;= {'a'}</td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>&lt;</td>
      <td>Verifica se un insieme è un vero subset</td>
      <td>lt(a, b)</td>
      <td>assert {'a'} &lt; {'a', 'b'}</td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>&lt;=</td>
      <td>Verifica se un insieme è un subset</td>
      <td>le(a, b)</td>
      <td>assert {'a'} &lt;= {'a'}</td>
      <td></td>
      <td></td>
    </tr>
  </tbody>
</table>

### Operatori di appartenenza in Python

Gli operatori di appartenenza “in” e “not in” in Python forniscono una dichiarazione sull’**inclusione di un oggetto in un insieme**.

<table>
  <thead>
    <tr>
      <th>Operatore Python</th>
      <th>Significato</th>
      <th>Funzione dell’operatore</th>
      <th>Esempio</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>in</td>
      <td>Verifica se un oggetto è contenuto in un’iterabile</td>
      <td>contains(a, b)</td>
      <td>'y' in 'Python'</td>
    </tr>
    <tr>
      <td>not in</td>
      <td>Negazione dell’operatore in</td>
      <td>not contains(a, b)</td>
      <td>'x' not in 'Python'</td>
    </tr>
  </tbody>
</table>

Gli operatori di appartenenza funzionano con **iterabili** e utilizzano un **controllo di uguaglianza** per determinare se l’oggetto di destinazione è incluso nell’insieme:

```none
'Py' in 'Python'
'Px' not in 'Python'
'Jack' in ['Jim', 'Jack']
```

L’uso dell’operatore in consente di evitare di scrivere il codice nella forma seguente:

```none
def my_in(target, collection):
    for element in collection:
        if element == target:
            return True
    return False
# test
word = 'Python'
letter = 'y'
assert (my_in(letter, word)) == (letter in word)
```

### Operatore di concatenazione

In Python, l’operatore di concatenazione viene utilizzato per **concatenare sequenze dello stesso tipo**. Il segno più viene utilizzato come simbolo dell’operatore.

<table>
  <thead>
    <tr>
      <th>Operatore Python</th>
      <th>Significato</th>
      <th>Funzione dell’operatore</th>
      <th>Esempio</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>+</td>
      <td>Concatena due sequenze</td>
      <td>add(a, b)</td>
      <td>\['Jim'\] + \['Jack', 'John'\]</td>
    </tr>
  </tbody>
</table>

Vediamo alcuni esempi. Concateniamo **due stringhe, due liste e due tuple**:

```none
assert "Walter" + "White" == 'WalterWhite'
assert ['a', 'b'] + ['c'] == ['a', 'b', 'c']
assert ('q', 'r') + ('s', 't') == ('q', 'r', 's', 't')
```

Python è utilizzato come [linguaggio di programmazione web](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/linguaggi-programmazione-web/ "Linguaggi programmazione web"). In questo contesto, l’operatore di concatenazione viene utilizzato per assemblare [tag HTML](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/tag-html/):

```none
site_title = 'Welcome'
print('<h1>' + site_title + '</h1>')
```

Nel confronto tra [Python e PHP](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/php-vs-python/) viene fatta una distinzione tra gli operatori di concatenazione dei due linguaggi. Questo perché PHP utilizza il punto “.” come simbolo. Lo stesso esempio mostrato in **PHP**:

```none
$siteTitle = 'Welcome';
echo '<h1>' . $siteTitle . '</h1>';
```

### Operatori di indice e di fetta

L’operatore indice in Python viene utilizzato per **estrarre** un elemento specifico di un insieme. L’operatore fetta (“slice” in inglese) viene utilizzato per estrarre una sottosequenza.

<table>
  <thead>
    <tr>
      <th>Operatore Python</th>
      <th>Significato</th>
      <th>Funzione dell’operatore</th>
      <th>Esempio</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>iterable\[index\]</td>
      <td>Restituisce l’elemento di un iterabile situato sotto l’indice</td>
      <td>getitem(iterable, index)</td>
      <td>'Python'\[1\] == 'y'</td>
    </tr>
    <tr>
      <td>sequence\[start:stop:step\]</td>
      <td>Restituisce una fetta di una sequenza</td>
      <td>getitem(iterable, slice(start, stop, step))</td>
      <td>'Python'\[0:1\] == 'Py', 'Python'\[0:-1:2\] == 'Pto'</td>
    </tr>
  </tbody>
</table>

Gli operatori indice e fetta di Python fanno uso interno del metodo Dunder *\_\_getitem\_\_()*, che viene richiamato con un indice numerico o con un oggetto fetta:

```none
names = ['Jim', 'Jack', 'John']
names[0] == names.__getitem__(0)
names[0:2] == names.__getitem__(slice(0, 2))
```

L’operatore fetta è utile perché consente di **estrarre una sottosequenza** senza usare un [ciclo for in Python](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/ciclo-for-su-python/) o un [ciclo while in Python](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/ciclo-while-in-python/). Questo evita ai programmatori di scrivere un codice nella forma seguente:

```none
word = 'Python'
start, stop, step = 0, 5, 2
index, substring = start, ''
while index in range(start, stop, step):
    substring += word[index]
    index += step
# test
assert substring == word[start:stop:step]
```


This is a markdown version of: [https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/operatori-python/](https://www.ionos.it/digitalguide/siti-web/programmazione-del-sito-web/operatori-python/) for AI/LLM consumption.