Hago esto:
a = 'hello'
Y ahora solo quiero una copia independiente de a :
import copy
b = str(a)
c = a[:]
d = a + ''
e = copy.copy(a)
map( id, [ a,b,c,d,e ] )
Fuera [3]:
[4365576160, 4365576160, 4365576160, 4365576160, 4365576160]
¿Por qué todos tienen la misma dirección de memoria y cómo puedo obtener una copia a?
python
string
python-2.7
yo habitual
fuente
fuente

d[ 'hello' ] = e, dondee[ 'hi' ] = 'again'. Para generar un diccionario anidado, generé un soloediccionario y lo copié varias veces. Noté que el consumo de memoria era muy bajo, lo que llevó a mi pregunta aquí. Ahora entiendo que no se crearon copias de cadena, de ahí el bajo consumo de memoria.bser una versión modificada deasin modificara, deja quebsea el resultado de cualquier operación. por ejemplo, seb = a[2:-1]estableceben'll'yapermanece 'hello'.Respuestas:
No necesitas copiar una cadena de Python. Son inmutables, y el
copymódulo siempre devuelve el original en tales casos, al igual questr()el segmento de cadena completo y se concatena con una cadena vacía.Además, tu
'hello'cuerda está internada ( ciertas cuerdas están ). Python intenta deliberadamente mantener una sola copia, ya que eso hace que las búsquedas en el diccionario sean más rápidas.Una forma de solucionar esto es crear una nueva cadena y luego volver a cortar esa cadena al contenido original:
>>> a = 'hello' >>> b = (a + '.')[:-1] >>> id(a), id(b) (4435312528, 4435312432)Pero todo lo que estás haciendo ahora es desperdiciar memoria. Después de todo, no es como si pudiera mutar estos objetos de cadena de alguna manera.
Si todo lo que quería saber es cuánta memoria requiere un objeto Python, use
sys.getsizeof(); le da la huella de memoria de cualquier objeto de Python.Para contenedores, esto no incluye el contenido; tendría que recurrir a cada contenedor para calcular un tamaño total de 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()) 360Luego, puede optar por utilizar el
id()seguimiento para tomar una huella de memoria real o para estimar una huella máxima si los objetos no se almacenaron en caché ni se reutilizaron.fuente
b = ''.join(a).Puede copiar una cadena en Python a través del formato de cadena:
>>> a = 'foo' >>> b = '%s' % a >>> id(a), id(b) (140595444686784, 140595444726400)fuente
b = '{:s}'.format(a)Acabo de comenzar algunas manipulaciones de cadenas y encontré esta pregunta. Probablemente estaba tratando de hacer algo como el OP, "yo habitual". Las respuestas anteriores no aclararon mi confusión, pero después de pensar un poco al respecto finalmente "lo entendí".
Mientras
a,b,c,d, yetienen el mismo valor, los que hacen referencia al mismo lugar. La memoria está guardada. Tan pronto como la variable comienza a tener diferentes valores, comienzan a tener diferentes referencias. Mi experiencia de aprendizaje provino de este código: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, eLa salida impresa es:
[4538504992, 4538504992, 4538504992, 4538504992, 4538504992] hello hello hello hello hello [6113502048, 4538504992, 4538504992, 4538504992, 5570935808] goodbye hello hello hello hello somethingfuente
La copia de una cadena se puede hacer de dos maneras, ya sea copiando la ubicación a = "a" b = a o puede clonar, lo que significa que b no se verá afectado cuando se cambie a, lo cual se hace mediante a = 'a' b = a [:]
fuente
Para decirlo de otra manera, "id ()" no es lo que te importa. Desea saber si el nombre de la variable se puede modificar sin dañar el nombre de la variable de origen.
>>> a = 'hello' >>> b = a[:] >>> c = a >>> b += ' world' >>> c += ', bye' >>> a 'hello' >>> b 'hello world' >>> c 'hello, bye'Si está acostumbrado a C, entonces estas son como variables de puntero, excepto que no puede des-referenciarlas para modificar a qué apuntan, pero id () le dirá dónde apuntan actualmente.
El problema para los programadores de Python surge cuando considera estructuras más profundas como listas o dictados:
>>> o={'a': 10} >>> x=o >>> y=o.copy() >>> x['a'] = 20 >>> y['a'] = 30 >>> o {'a': 20} >>> x {'a': 20} >>> y {'a': 30}Aquí oyx se refieren al mismo dict o ['a'] yx ['a'], y ese dict es "mutable" en el sentido de que puede cambiar el valor de la clave 'a'. Es por eso que "y" debe ser una copia y y ['a'] puede referirse a otra cosa.
fuente