2014-07-17 15 views
42

faccio questo:Come posso copiare una stringa Python?

a = 'hello' 

E ora voglio solo una copia indipendente di a:

import copy 

b = str(a) 
c = a[:] 
d = a + '' 
e = copy.copy(a) 

map(id, [ a,b,c,d,e ]) 

Out [3]:

[4365576160, 4365576160, 4365576160, 4365576160, 4365576160] 

Perché tutti hanno lo stesso indirizzo di memoria e come posso ottenere una copia di a?

+2

Per ottenere risposta diversa da di Martijin (che è del tutto corretto, anche se non necessariamente rispondere alla domanda come detto) si potrebbe vuoi fornire più dettagli/casi d'uso per mostrare ** perché ** vuoi copiarlo. – elmo

+4

Come suggerisce @elemo, questo potrebbe essere un [problema XY] (http://www.perlmonks.org/?node=XY+Problem). – martineau

+2

Ero interessato a stimare l'utilizzo della memoria di un dizionario annidato del modulo 'd ['hello'] = e', dove' e ['hi'] = 'again''. Per generare un dizionario nidificato, ho generato un singolo dizionario 'e' e l'ho copiato più volte. Ho notato che il consumo di memoria era molto basso, il che ha portato alla mia domanda qui. Ora capisco che non sono state create copie di stringa, quindi il basso consumo di memoria. –

risposta

92

Non è necessario copiare una stringa Python. Sono immutabili e il modulo copy restituisce sempre l'originale in questi casi, come lo str(), l'intera sezione della stringa e la concatenazione con una stringa vuota.

Inoltre, la stringa 'hello' è internata (certain strings are). Python cerca deliberatamente di mantenere solo una copia, in quanto rende le ricerche del dizionario più veloci.

Un modo si potrebbe ovviare a questo è quello di creare effettivamente una nuova stringa, poi affettare la stringa di nuovo al contenuto originale:

>>> a = 'hello' 
>>> b = (a + '.')[:-1] 
>>> id(a), id(b) 
(4435312528, 4435312432) 

Ma tutto quello che state facendo ora è la memoria dei rifiuti. Non è come se si potesse mutare questi oggetti stringa in qualsiasi modo, dopo tutto.

Se tutto ciò che si desidera sapere è la quantità di memoria richiesta da un oggetto Python, utilizzare sys.getsizeinfo(); ti dà l'impronta di memoria di qualsiasi oggetto Python.

Per i contenitori questo è non includere i contenuti; che avrebbe dovuto ricorsivamente in ogni contenitore per calcolare una dimensione totale della memoria:

>>> import sys 
>>> a = 'hello' 
>>> sys.getsizeof(a) 
42 
>>> b = {'foo': 'bar'} 
>>> sys.getsizeof(b) 
280 
>>> sys.getsizeof(b) + sum(sys.getsizeof(k) + sys.getsizeof(v) for k, v in b.items()) 
360 

È quindi possibile scegliere di utilizzare il monitoraggio id() di prendere un footprint di memoria reale o di stimare un ingombro massimo se gli oggetti non sono stati memorizzati nella cache e riutilizzati .

+3

C'è più di un solo modo per creare un nuovo oggetto stringa, come ad esempio 'b = '' .join (a)'. – martineau

+0

@martineau: certo, volevo davvero dire "a senso unico". –

+10

Enfasi su "Non è necessario copiare una stringa Python". C'è una ragione per cui queste operazioni restituiscono semplicemente la stessa stringa. – tcooc

3

È possibile copiare una stringa in pitone via formattazione delle stringhe:

>>> a = 'foo' 
>>> b = '%s' % a 
>>> id(a), id(b) 
(140595444686784, 140595444726400) 
-1

Copia di una stringa può essere fatto in due modi copiare la posizione un = "a" b = a oppure è possibile clonare il che significa b wont viene influenzato quando viene cambiato un a = 'a' b = a [:]

2

Sto solo iniziando alcune manipolazioni di stringhe e ho trovato questa domanda. Probabilmente stavo cercando di fare qualcosa come l'OP, "al solito me". Le risposte precedenti non hanno chiarito la mia confusione, ma dopo averci pensato un po ', alla fine ho "capito".

Finché a, b, c, d, e e hanno lo stesso valore, riferimento nello stesso posto. La memoria è salvata Non appena la variabile inizia ad avere valori diversi, iniziano ad avere riferimenti diversi.La mia esperienza di apprendimento è venuto da questo codice:

import copy 
a = 'hello' 
b = str(a) 
c = a[:] 
d = a + '' 
e = copy.copy(a) 

print map(id, [ a,b,c,d,e ]) 

print a, b, c, d, e 

e = a + 'something' 
a = 'goodbye' 
print map(id, [ a,b,c,d,e ]) 
print a, b, c, d, e 

La stampa è:

[4538504992, 4538504992, 4538504992, 4538504992, 4538504992] 

hello hello hello hello hello 

[6113502048, 4538504992, 4538504992, 4538504992, 5570935808] 

goodbye hello hello hello hello something 
+0

Altri dettagli per il comportamento sono descritti in questo post https://stackoverflow.com/questions/2123925/when-does-python-allocate-new-memory-for-identical-strings – dlasalle

Problemi correlati