2013-01-21 15 views
25

sto solo imparando pitone e sto andando anche se i tutorial su https://developers.google.com/edu/python/stringsPython perché si usa [:] over =

Sotto le String Fette sezione

s [:] è ' Ciao' - omettendo sia sempre ci dà una copia di tutta la cosa (questo è il modo divinatorio per copiare una sequenza come una stringa o lista)

out di curiosità perché non dovresti semplicemente usare un operatore =?

s = 'hello'; 
bar = s[:] 
foo = s 

Per quanto posso dire sia bar e foo hanno lo stesso valore.

+6

Non sarei d'accordo con la frase, questo non è il modo pitone per copiare una stringa. Sei corretto che useresti semplicemente un '='. Per le liste è una storia diversa. – wim

risposta

40

= fa riferimento, utilizzando [:] si crea una copia. Per le stringhe, che sono immutabili, questo non importa, ma per gli elenchi ecc. È fondamentale.

>>> s = 'hello' 
>>> t1 = s 
>>> t2 = s[:] 
>>> print s, t1, t2 
hello hello hello 
>>> s = 'good bye' 
>>> print s, t1, t2 
good bye hello hello 

ma:

>>> li1 = [1,2] 
>>> li = [1,2] 
>>> li1 = li 
>>> li2 = li[:] 
>>> print li, li1, li2 
[1, 2] [1, 2] [1, 2] 
>>> li[0] = 0 
>>> print li, li1, li2 
[0, 2] [0, 2] [1, 2] 

Allora perché lo usano quando si tratta con le stringhe? Le stringhe incorporate sono immutabili, ma ogni volta che scrivi una funzione di libreria che prevede una stringa, un utente potrebbe darti qualcosa che "assomiglia ad una stringa" e "si comporta come una stringa", ma è un tipo personalizzato. Questo tipo potrebbe essere mutabile, quindi è meglio prendersene cura.

Tale tipo potrebbe sembrare:

class MutableString(object): 
    def __init__(self, s): 
     self._characters = [c for c in s] 

    def __str__(self): 
     return "".join(self._characters) 

    def __repr__(self): 
     return "MutableString(\"%s\")" % str(self) 

    def __getattr__(self, name): 
     return str(self).__getattribute__(name) 

    def __len__(self): 
     return len(self._characters) 

    def __getitem__(self, index): 
     return self._characters[index] 

    def __setitem__(self, index, value): 
     self._characters[index] = value 

    def __getslice__(self, start, end=-1, stride=1): 
     return str(self)[start:end:stride] 


if __name__ == "__main__": 
    m = MutableString("Hello") 
    print m 
    print len(m) 
    print m.find("o") 
    print m.find("x") 
    print m.replace("e", "a") #translate to german ;-) 
    print m 
    print m[3] 
    m[1] = "a" 
    print m 
    print m[:] 

    copy1 = m 
    copy2 = m[:] 
    print m, copy1, copy2 
    m[1] = "X" 
    print m, copy1, copy2 

Disclaimer: Questo è solo un esempio per mostrare come potrebbe funzionare e per motivare l'uso di [:]. Non è testato, incompleto e probabilmente è orribilmente performante

+2

+1 per il '#translate al tedesco ;-)' – root

+2

Per favore dimmi che hai già avuto una lezione del genere, e non ho messo insieme tutto questo solo per una risposta come questa :) –

+0

Scusa, devo deluderti ;-) Se guardi la cronologia dei commit della mia risposta, puoi vederla crescere. –

1

Hanno lo stesso valore, ma c'è una differenza fondamentale quando si tratta di oggetti mutabili.

Dire foo = [1, 2, 3]. Assegnare bar = foo e baz = foo[:]. Supponiamo che vogliate cambiare bar - bar.append(4). Si controlla il valore di foo, e ...

print foo 
# [1, 2, 3, 4] 

Ora, dove ha fatto che in più 4 provengono da? È perché hai assegnato bar a l'identità di foo, quindi quando ne cambi uno cambia l'altro. Si modifica baz - baz.append(5), ma non è successo nulla agli altri due: è perché è stata assegnata una copia di foo a baz.

Si noti tuttavia che poiché le stringhe sono immutabili, non importa.

0

Se ha un elenco il risultato è diverso:

l = [1,2,3] 
l1 = l 
l2 = l[:] 

l2 è una copia di l (oggetto diverso) mentre l1 è un alias di l che significa che l1 [0] = 7 modificherà anche l, mentre l2 [1] = 7 non modificherà l.

0

Mentre fare riferimento a un oggetto e fare riferimento alla copia dell'oggetto non differisce per un oggetto immutabile come la stringa, lo fanno per gli oggetti mutabili (e i metodi mutabili), ad esempio l'elenco.

stessa cosa su oggetti mutabili:

a = [1,2,3,4] 
b = a 
c = a[:] 
a[0] = -1 
print a # will print [1,2,3,4] 
print b # will print [-1,2,3,4] 
print c # will print [1,2,3,4] 

Una visualizzazione sul pythontutor dell'esempio precedente - http://goo.gl/Aswnl.