Eu faço isso:
a = 'hello'
E agora eu só quero uma cópia independente de a
:
import copy
b = str(a)
c = a[:]
d = a + ''
e = copy.copy(a)
map( id, [ a,b,c,d,e ] )
Fora [3]:
[4365576160, 4365576160, 4365576160, 4365576160, 4365576160]
Por que todos eles têm o mesmo endereço de memória e como posso obter uma cópia dele a
?
python
string
python-2.7
sempre eu
fonte
fonte
d[ 'hello' ] = e
, ondee[ 'hi' ] = 'again'
. Para gerar esse dicionário aninhado, gerei um únicoe
dicionário e copiei-o várias vezes. Percebi que o consumo de memória estava muito baixo, o que me levou à minha dúvida aqui. Agora eu entendo que nenhuma cópia de string foi criada, daí o baixo consumo de memória.b
ser uma versãoa
modificada sem modificara
, deixeb
ser o resultado de qualquer operação. por exemplo,b = a[2:-1]
defineb
para'll'
ea
permanece 'hello'
.Respostas:
Você não precisa copiar uma string Python. Eles são imutáveis, e o
copy
módulo sempre retorna o original em tais casos, assim comostr()
toda a fatia da string e concatenando com uma string vazia.Além disso, sua
'hello'
string está internada ( algumas strings estão ). Python tenta deliberadamente manter apenas uma cópia, pois isso torna as pesquisas no dicionário mais rápidas.Uma maneira de contornar isso é criar uma nova string e, em seguida, fatiar essa string de volta ao conteúdo original:
>>> a = 'hello' >>> b = (a + '.')[:-1] >>> id(a), id(b) (4435312528, 4435312432)
Mas tudo o que você está fazendo agora é desperdiçar memória. Afinal, não é como se você pudesse transformar esses objetos string de qualquer maneira.
Se tudo que você deseja saber é quanta memória um objeto Python requer, use
sys.getsizeof()
; ele fornece a pegada de memória de qualquer objeto Python.Para contêineres, isso não inclui o conteúdo; você teria que recurse em cada contêiner para calcular o tamanho total da memória:
>>> 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
Você pode escolher usar o
id()
rastreamento para obter uma pegada de memória real ou para estimar uma pegada máxima se os objetos não foram armazenados em cache e reutilizados.fonte
b = ''.join(a)
.Você pode copiar uma string em Python por meio da formatação de string:
>>> a = 'foo' >>> b = '%s' % a >>> id(a), id(b) (140595444686784, 140595444726400)
fonte
b = '{:s}'.format(a)
Estou apenas começando algumas manipulações de string e encontrei esta questão. Eu provavelmente estava tentando fazer algo como o OP, "sempre eu". As respostas anteriores não esclareceram minha confusão, mas depois de pensar um pouco sobre isso, finalmente "entendi".
Enquanto
a
,b
,c
,d
, ee
têm o mesmo valor, eles fazem referência ao mesmo lugar. A memória é salva. Assim que as variáveis passam a ter valores diferentes, elas passam a ter referências diferentes. Minha experiência de aprendizado veio deste 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, e
A saída impressa é:
[4538504992, 4538504992, 4538504992, 4538504992, 4538504992] hello hello hello hello hello [6113502048, 4538504992, 4538504992, 4538504992, 5570935808] goodbye hello hello hello hello something
fonte
Copiar uma string pode ser feito de duas maneiras: copie o local a = "a" b = a ou você pode clonar, o que significa que b não será afetado quando a for alterado, o que é feito por a = 'a' b = a [:]
fonte
Em outras palavras, "id ()" não é o que importa. Você deseja saber se o nome da variável pode ser modificado sem prejudicar o nome da variável de origem.
>>> a = 'hello' >>> b = a[:] >>> c = a >>> b += ' world' >>> c += ', bye' >>> a 'hello' >>> b 'hello world' >>> c 'hello, bye'
Se você está acostumado com C, então elas são como variáveis de ponteiro, exceto que você não pode desreferenciá-las para modificar para onde elas apontam, mas id () lhe dirá para onde elas apontam atualmente.
O problema para os programadores Python surge quando você considera estruturas mais profundas, como listas ou dictes:
>>> o={'a': 10} >>> x=o >>> y=o.copy() >>> x['a'] = 20 >>> y['a'] = 30 >>> o {'a': 20} >>> x {'a': 20} >>> y {'a': 30}
Aqui, o e x referem-se ao mesmo dict o ['a'] e x ['a'], e esse dict é "mutável" no sentido de que você pode alterar o valor da chave 'a'. É por isso que "y" precisa ser uma cópia e y ['a'] pode se referir a outra coisa.
fonte