Skip to content

Come tagliare una lista, una stringa, una tupla in Python

Python

In Python, usando una slice (es:[2:5:2]), you can extract a subsequence of a sequence object, such as a list, string, tuple, etc.

In questo articolo vengono descritti i seguenti contenuti.

  • Utilizzo di base delle fette
    • [inizio: bene]
    • [inizio:stop:passo]
  • Estrarre dalla fine con un valore negativo
    • Valori negativi per start e stop
    • Valori negativi per passo
  • Taglia oggetto per porzione()
  • Assegnazione di valori per sezioni
  • Fette per un elenco di elenchi
  • Le fette fanno una copia superficiale
  • Fette per archi e tuple

Utilizzo di base delle fette

[inizio: bene]

In una sezione, la posizione iniziale di inizio e la posizione finale di arresto della sottosequenza vengono scritte come [inizio: arresto].

L’intervallo inizia <= x

l = [0, 10, 20, 30, 40, 50, 60]

print(l[2:5])
# [20, 30, 40]

Puoi pensare alle posizioni (indici) per la fetta come puntate tra gli elementi.

Un modo per imparare a scrivere liberamente come le sezioni è pensare a un bordo con i punti del primo carattere numerato 0.
3. Un’introduzione a Python – Stringhe — Python documentazione 3.10.4

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
 0   1   2   3   4   5   6
-6  -5  -4  -3  -2  -1

Quanto sopra è un esempio per le stringhe, ma lo stesso vale per liste, tuple, ecc. Il caso dei valori negativi è descritto più avanti.

Se si omette inizio, la sottosequenza viene estratta dall’inizio, se si omette stop, la sottosequenza viene estratta fino alla fine. Se entrambi vengono omessi, tutti gli elementi vengono estratti.

print(l[:3])
# [0, 10, 20]

print(l[3:])
# [30, 40, 50, 60]

print(l[:])
# [0, 10, 20, 30, 40, 50, 60]

Fuori dal limite

Non viene generato alcun errore se si specifica una posizione che supera il numero di elementi.

print(l[2:10])
# [20, 30, 40, 50, 60]

Se nessun elemento è selezionato

Non viene generato alcun errore se si specifica start e stop che non selezionano alcun elemento. Viene restituito un elenco vuoto.

print(l[5:2])
# []

print(l[2:2])
# []

print(l[10:20])
# []

[inizio:stop:passo]

Oltre alla posizione iniziale di inizio e fine della posizione di arresto, è possibile specificare il passaggio come [inizio:arresto:passaggio].

Ad esempio, se il passo è impostato su 2, è possibile selezionare elementi in posizioni dispari o pari.

print(l[::2])
# [0, 20, 40, 60]

print(l[1::2])
# [10, 30, 50]

Altri esempi:

print(l[::3])
# [0, 30, 60]

print(l[2:5:2])
# [20, 40]

Come negli esempi precedenti, se il passo viene omesso, viene impostato su 1.

Valori negativi per start e stop

Se start e stop sono specificati con valori negativi, vengono considerate come posizioni dalla fine.

-1 indica l’ultimo elemento.

Se stop=-1, l’elemento allo stop non è incluso, quindi viene selezionato il valore secondo dalla fine.

print(l[3:-1])
# [30, 40, 50]

Di seguito viene riformulato il concetto delle posizioni (indici) per la fetta.

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
 0   1   2   3   4   5   6
-6  -5  -4  -3  -2  -1

Altri esempi:

print(l[-2:])
# [50, 60]

print(l[-5:-2])
# [20, 30, 40]

Valori negativi per passo

Se il passo è specificato come valore negativo, gli elementi vengono selezionati in ordine inverso.

Gli elementi vengono selezionati dalla posizione iniziale. Si noti che a meno che l’inizio non indichi una posizione dopo l’arresto, sarà vuoto.

print(l[5:2:-1])
# [50, 40, 30]

print(l[2:5:-1])
# []

Altri esempi:

print(l[-2:-5:-1])
# [50, 40, 30]

print(l[-2:2:-1])
# [50, 40, 30]

print(l[5:2:-2])
# [50, 30]

Omettendo start e stop e impostando il passo su -1, puoi ottenere un oggetto invertito.

print(l[::-1])
# [60, 50, 40, 30, 20, 10, 0]

Puoi anche usare reverse() e reversed() per invertire elenchi o stringhe, tuple e così via. Per i dettagli, vedere il seguente articolo.

Taglia oggetto per porzione()

Puoi generare un oggetto slice usando la funzione integrata slice(). Se si desidera selezionare gli elementi nella stessa posizione, è necessario generare l’oggetto solo una volta.

slice(start, stop, step) equivale a start:stop:step.

sl = slice(2, 5, 2)
print(sl)
# slice(2, 5, 2)

print(type(sl))
# <class 'slice'>

print(l[sl])
# [20, 40]

Se vengono specificati due argomenti, il passaggio viene impostato su Nessuno. Questo equivale a un inizio:stop.

sl = slice(2, 5)
print(sl)
# slice(2, 5, None)

print(l[sl])
# [20, 30, 40]

Se viene specificato un solo argomento, start e step vengono impostati su Nessuno. Questo equivale a: basta.

sl = slice(2)
print(sl)
# slice(None, 2, None)

print(l[sl])
# [0, 10]

Se tutti gli argomenti vengono omessi, viene generato un errore TypeError. Se vuoi generare: con slice(), specifica specifica Nessuno.

# sl = slice()
# TypeError: slice expected at least 1 arguments, got 0

sl = slice(None)
print(sl)
# slice(None, None, None)

print(l[sl])
# [0, 10, 20, 30, 40, 50, 60]

Assegnazione di valori per sezioni

È possibile aggiungere nuovi valori all’intervallo selezionato dalle sezioni.

Non importa se selezionato il numero di elementi nell’intervallo selezionato per affettare non corrisponde al numero di elementi (= la lunghezza dell’oggetto) da selezionare.

print(l)
# [0, 10, 20, 30, 40, 50, 60]

l[2:5] = [200, 300, 400]
print(l)
# [0, 10, 200, 300, 400, 50, 60]

l[2:5] = [-2, -3]
print(l)
# [0, 10, -2, -3, 50, 60]

l[2:4] = [2000, 3000, 4000, 5000]
print(l)
# [0, 10, 2000, 3000, 4000, 5000, 50, 60]

l[2:6] = [20000]
print(l)
# [0, 10, 20000, 50, 60]

Si noti che specificando un valore scalare sul lato destro risulterà TypeError.

# l[2:3] = 200
# TypeError: can only assign an iterable

Se il lato destro è vuoto, gli elementi nell’intervallo selezionato dalla sezione verranno eliminati.

l[1:4] = []
print(l)
# [0, 60]

È anche possibile specificare un intervallo fuori intervallo o vuoto per l’assegnazione. Il valore sul lato destro viene inserito nella posizione specificata.

l[20:60] = [-1, -2, -3]
print(l)
# [0, 60, -1, -2, -3]

l[2:2] = [-100]
print(l)
# [0, 60, -100, -1, -2, -3]

Se il numero di elementi non è uguale per l’intervallo in cui è specificato il passaggio, viene generato un errore ValueError.

print(l[:5:2])
# [0, -100, -2]

l[:5:2] = [100, 200, 300]
print(l)
# [100, 60, 200, -1, 300, -3]

# l[:5:2] = [100, 200]
# ValueError: attempt to assign sequence of size 2 to extended slice of size 3

Per aggiungere un elemento nel mezzo o alla fine dell’elenco, vengono forniti metodi come insert() e append(). Vedi il seguente articolo:

Fette per un elenco di elenchi

Quando si applica una sezione a un elenco di elenchi (= elenco 2D), vengono selezionati gli elenchi interni.

l_2d = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]

print(l_2d[1:3])
# [[3, 4, 5], [6, 7, 8]]

Per applicare una sezione agli elenchi interni, usa la comprensione degli elenchi.

print([l[:2] for l in l_2d[1:3]])
# [[3, 4], [6, 7]]

Se vuoi ottenere una colonna, puoi trasporla.

l_2d_t = [list(x) for x in zip(*l_2d)]
print(l_2d_t)
# [[0, 3, 6, 9], [1, 4, 7, 10], [2, 5, 8, 11]]

print(l_2d_t[1])
# [1, 4, 7, 10]

Nota che puoi usare NumPy, è più facile usare NumPy per manipolare array multidimensionali.

In NumPy, puoi specificare una sezione per ogni dimensione come [1:4, 2:5].

Le fette fanno una copia superficiale

Affettare fa una copia superficiale. Per ulteriori informazioni sulla copia superficiale e profonda, vedere il seguente articolo.

Ad esempio, nel caso di una lista di numeri, l’assegnazione del risultato ottenuto con lo slicing ad una variabile e l’aggiornamento degli elementi della variabile non modificherà l’oggetto originale.

l = [0, 10, 20, 30, 40, 50, 60]

l_slice = l[2:5]
print(l_slice)
# [20, 30, 40]

l_slice[1] = 300
print(l_slice)
# [20, 300, 40]

print(l)
# [0, 10, 20, 30, 40, 50, 60]

Nel caso di oggetti composti che contengono, manuali, ecc. come elementi, l’aggiornamento di un elemento cambia l’oggetto originale.

l_2d = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]

l_2d_slice = l_2d[1:3]
print(l_2d_slice)
# [[3, 4, 5], [6, 7, 8]]

l_2d_slice[0][1] = 400
print(l_2d_slice)
# [[3, 400, 5], [6, 7, 8]]

print(l_2d)
# [[0, 1, 2], [3, 400, 5], [6, 7, 8], [9, 10, 11]]

Nell’esempio precedente, l’elenco nella sezione viene aggiornato e viene modificato anche l’elenco nell’oggetto originale. Se l’elenco nell’oggetto originale viene aggiornato, viene modificato anche l’elenco nella sezione.

Per evitare ciò, importa il modulo di copia della libreria standard e usa deepcopy().

import copy

l_2d = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]

l_2d_slice_deepcopy = copy.deepcopy(l_2d[1:3])
print(l_2d_slice_deepcopy)
# [[3, 4, 5], [6, 7, 8]]

l_2d_slice_deepcopy[0][1] = 400
print(l_2d_slice_deepcopy)
# [[3, 400, 5], [6, 7, 8]]

print(l_2d)
# [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]

Fette per archi e tuple

Finora abbiamo mostrato esempi di liste (tipo di lista), ma le fette possono essere usate anche con altri oggetti sequenza come stringhe str e tuple tuple.

Tuttavia, str e tuple sono immutabili, quindi non è possibile presentare nuovi valori.

s = 'abcdefg'

print(s[2:5])
# cde

print(s[::-1])
# gfedcba

# s[2:5] = 'CDE'
# TypeError: 'str' object does not support item assignment

t = (0, 10, 20, 30, 40, 50, 60)

print(t[2:5])
# (20, 30, 40)

# t[2:5] = (200, 300, 400)
# TypeError: 'tuple' object does not support item assignment

Vedere il seguente articolo per dividere e sostituire le stringhe.