2010-11-15 22 views

risposta

9

Python permette di " affettare "vari tipi di contenitori; questa è una notazione abbreviata per prendere alcune sottoraccolte di una collezione ordinata. Per esempio, se si dispone di un elenco

foo = [1,2,3,4,5] 

e si desidera che il secondo, terzo e quarto elemento, si può fare:

foo[1:4] 

Se si omette uno dei numeri nella fetta, si il valore predefinito è all'inizio della lista. Così, per esempio

foo[1:] == [2,3,4,5] 
foo[:4] == [1,2,3,4] 

Naturalmente, se si omette entrambi i numeri nella fetta si otterrà l'intero elenco indietro! Tuttavia, riceverai una copia della lista invece dell'originale; in effetti, questa è la notazione standard per copiare una lista. Si noti la differenza:

>>> a = [1,2,3,4] 
>>> b = a 
>>> b.append(5) 
>>> a 
[1, 2, 3, 4, 5] 
>>> 
>>> a = [1,2,3,4] 
>>> b = a[:] 
>>> b.append(5) 
>>> a 
[1, 2, 3, 4] 

Ciò si verifica perché b = a dice b per puntare allo stesso oggetto come a, quindi aggiungendo al b è lo stesso aggiungendo al a. La copia dell'elenco a evita questo. Si noti che questo esegue solo un livello di profondità indiretta - se a contenesse un elenco, ad esempio, e si aggiungesse a quell'elenco in b, si cambierebbe comunque a.

A proposito, c'è un terzo argomento opzionale per la fetta, che è un parametro passo - vi permette di scorrere la lista in salti superiori a 1. Così si potrebbe scrivere gamma (100) [ 0: 2] per tutti i numeri pari fino a 100.

+1

o è possibile scrivere intervallo (0, 100, 2) –

+0

può anche essere utilizzato per assegnare a una sezione, ad esempio 'a [2: 4] = [4,5,6,7,8]' –

5

Se self.var è un mutable sequence, restituirà un shallow copy di tale sequenza.

Se self.var è un immutabile built-in sequence come un string o un tuple molte implementazioni torneranno self.var stessa.

+0

-1 Se var fa riferimento a una ** sequenza ** mutabile, restituirà un ** riferimento a ** una copia superficiale di tale sequenza. Se var si riferisce a una sequenza immutabile (ad esempio str, unicode, tuple), dovrebbe (per l'efficienza) restituire il riferimento originale. –

+0

@John, la prima parte del tuo commento è tecnicamente corretta, ma non sono sicuro della seconda parte (vedi l'ultimo link nella mia risposta). Inoltre, penso che l'interrogante sia più interessato a ciò che il codice effettivamente * fa * invece di ciò che * dovrebbe * fare :) –

+0

Amplificazione di "should": il secondo caso con CPython restituirà il riferimento originale per gli oggetti built-in (perché il gli implementatori non sono sciocchi). Nessuna garanzia per oggetti definiti dall'utente. "Shared slice" (il tuo ultimo link) è irrilevante nel caso "[:]" che è già "condiviso" da implementazioni non sciocche. –

2

Ciò creerà una copia superficiale dell'elenco e la restituirà.

"Copia superficiale", al contrario di "copia profonda", significa che l'elenco creerà solo nuove copie dei riferimenti in esso, non gli oggetti reali. Cioè, verrà creata una nuova lista con gli stessi riferimenti all'oggetto, ma gli oggetti stessi rimarranno gli stessi.

Se si rimuove un elemento dall'originale, il nuovo elenco non sarà interessato, ma se si modifica uno degli elementi all'interno di nell'elenco originale (chiamando un metodo o impostando una proprietà dell'oggetto, ad esempio), l'elemento cambierà anche nel nuovo elenco, perché sebbene siano elenchi diversi, puntano agli stessi oggetti.

+0

Chi dice che è un elenco? Potrebbe essere qualsiasi oggetto che supporta l'operazione di taglio, ad es. un oggetto xlm.etree.ElementTree.Element –

+0

Certo, hai ragione. Avrei potuto dire "qualsiasi oggetto che implementa funzionalità di slicing", ma penso che avrebbe difficilmente aiutato - non il punto della domanda, per quanto ne so, penso che il problema della copia superficiale rispetto a quella profonda fosse la parte importante. – slezica

2

Si chiama Lista affettare:

[da: a: salta]

[da: a]

Quindi, se io dico:

list = range(20) 
print list[1:3] #returns [2, 3] 
print list[1:12:3] #returns [2, 5, 8, 11] 
print list[14:] #because theres no end: [15, 16, 17, 18, 19] 
print list[14:-2] #-2 from the end: [15, 16, 17] 
+0

Si chiama slicing, un'operazione fornita da diversi tipi di oggetti. –

1

è possibile utilizzare gli operatori con un elenco dei seguenti modi:

list = [] 1,2,3,4,5,6,7,8,9

con un singolo: in al centro delle parentesi si definisce l'intervallo da quale posizione a quale posizione scegliere (la posizione iniziale è 0. quindi ho le seguenti opzioni

lista [0: 3] mostra [1,2,3], causa inizia dalla posizione del primo numero e termina sulla posizione precedente al secondo numero

lista [: 3] mostra lo stesso di prima, il primo numero è assente quindi non c'è limite iniziale

lista [5:] mostra l'elenco dalla quinta posizione alla fine [6,7,8,9]

Ora se xey dalla lista [x, y] è negativo allora inizia se è x dalla posizione x e se è y finisce da len (lista) -2 posizione Ad esempio: lista [- 1: 3] = [2,3]

Ora è possibile avere 2: come [x: y: z] qui x indica la cella iniziale, y l'ultima cella (che non è inclusa nell'intervallo restituito) e z il passo in cui la sequenza avanza lista [0: 5: 2] = [0,2,4]