Meu entendimento era que as strings Python são imutáveis.
Tentei o seguinte código:
a = "Dog"
b = "eats"
c = "treats"
print a, b, c
# Dog eats treats
print a + " " + b + " " + c
# Dog eats treats
print a
# Dog
a = a + " " + b + " " + c
print a
# Dog eats treats
# !!!
O Python não deveria ter impedido a atribuição? Provavelmente estou perdendo alguma coisa.
Qualquer ideia?
python
string
immutability
mutability
Jason
fonte
fonte
id()
função.a
terá um id diferente antes e depois da atribuição, indicando que está apontando para objetos diferentes. Da mesma forma com código comob = a
você encontraráa
eb
terá o mesmo id, indicando que eles estão fazendo referência ao mesmo objeto.Respostas:
Primeiro
a
apontou para a string "Dog". Em seguida, você alterou a variávela
para apontar para uma nova string "Dog come trata". Você não alterou a string "Dog". Strings são imutáveis, variáveis podem apontar para o que quiserem.fonte
Os próprios objetos string são imutáveis.
A variável,
a
que aponta para a string, é mutável.Considerar:
fonte
a.append(3)
não é o mesmo quea = a + 3
. Não é uniformea += 3
(adição inplace é equivalente a.extend
, não a.append
).+
se comporta da mesma forma para listas e strings - ele concatena criando uma nova cópia e não altera nenhum operando.append
função porque são imutáveis.A variável a está apontando para o objeto "Cachorro". É melhor pensar na variável em Python como uma tag. Você pode mover a tag para objetos diferentes, que é o que você fez quando mudou
a = "dog"
paraa = "dog eats treats"
.No entanto, a imutabilidade se refere ao objeto, não à tag.
Se você tentasse
a[1] = 'z'
fazer"dog"
em"dzg"
, obteria o erro:porque as strings não suportam atribuição de itens, portanto, são imutáveis.
fonte
Algo é mutável apenas quando somos capazes de alterar os valores mantidos no local da memória sem alterar o próprio local da memória.
O truque é: se você descobrir que a localização da memória antes e depois da alteração é a mesma, ela é mutável.
Por exemplo, a lista é mutável. Quão?
Uma string é imutável. Como podemos provar isso?
Nós temos
Portanto, falhamos na mutação da string. Isso significa que uma string é imutável.
Ao reatribuir, você altera a variável para apontar para um novo local. Aqui você não alterou a string, mas alterou a própria variável. A seguir está o que você está fazendo.
id
antes e depois da reatribuição é diferente, então isso prova que você não está realmente sofrendo mutação, mas apontando a variável para um novo local. O que não é uma mutação dessa string, mas uma mutação dessa variável.fonte
Uma variável é apenas um rótulo apontando para um objeto. O objeto é imutável, mas você pode fazer o rótulo apontar para um objeto completamente diferente, se desejar.
fonte
Considerar:
Observe que a localização da memória hexadecimal não mudou quando armazenei o mesmo valor na variável duas vezes. Ele mudou quando armazenei um valor diferente. A string é imutável. Não por zelo, mas porque você paga a penalidade de desempenho de criar um novo objeto na memória. A variável
a
é apenas um rótulo apontando para aquele endereço de memória. Ele pode ser alterado para apontar para qualquer coisa.fonte
A instrução
a = a + " " + b + " " + c
pode ser dividida com base em ponteiros.a + " "
diz para me dar o quea
aponta, o que não pode ser alterado e adicionar" "
ao meu conjunto de trabalho atual.memória:
+ b
diz para me dar o queb
aponta, o que não pode ser alterado, e adicioná-lo ao conjunto de trabalho atual.memória:
+ " " + c
diz adicionar" "
ao conjunto atual. Em seguida, dê-me o quec
aponta, o que não pode ser alterado, e adicione-o ao conjunto de trabalho atual. memória:Por fim,
a =
diz definir meu ponteiro para apontar para o conjunto resultante.memória:
"Dog"
é recuperado, porque não há mais ponteiros se conectando a seu pedaço de memória. Nunca modificamos a seção de memória"Dog"
em que residia, que é o que significa imutável. No entanto, podemos alterar quais rótulos, se houver, apontam para essa seção da memória.fonte
fonte
Há uma diferença entre os dados e o rótulo ao qual estão associados. Por exemplo, quando você faz
os dados
"dog"
são criados e colocados sob o rótuloa
. O rótulo pode mudar, mas o que está na memória não. Os dados"dog"
ainda existirão na memória (até que o coletor de lixo os exclua) depois que você fizerEm seu programa
a
agora ^ aponta para ^"cat"
mas a string"dog"
não mudou.fonte
As strings Python são imutáveis. No entanto,
a
não é uma string: é uma variável com um valor de string. Você não pode alterar a string, mas pode alterar o valor da variável para uma nova string.fonte
As variáveis podem apontar para qualquer lugar que desejarem. Um erro será gerado se você fizer o seguinte:
fonte
Os objetos de string do Python são imutáveis. Exemplo:
Neste exemplo, podemos ver que quando atribuímos valores diferentes em um, ele não se modifica. Um novo objeto é criado.
E não pode ser modificado. Exemplo:
Ocorreu um erro.
fonte
'mutável' significa que podemos alterar o conteúdo da string, 'imutável' significa que não podemos adicionar uma string extra.
fonte
>>> a = 'dogs'
>>> a.replace('dogs', 'dogs eat treats')
'dogs eat treats'
>>> print a
'dogs'
Imutável, não é ?!
A parte da mudança variável já foi discutida.
fonte
replace()
método retorna uma nova string.Considere esta adição ao seu exemplo
Uma das explicações mais precisas que encontrei em um blog é:
Link para o blog: https://jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-neither/
fonte
Adicionando um pouco mais às respostas mencionadas acima.
id
de uma variável muda após a reatribuição.O que significa que alteramos a variável
a
para apontar para uma nova string. Agora existem doisstring
objetos (str):'initial_string'
comid
= 139982120425648e
'new_string'
comid
= 139982120425776Considere o código abaixo:
Agora,
b
aponta para'initial_string'
e tem o mesmoid
quea
tinha antes da reatribuição.Portanto, o
'intial_string'
não sofreu mutação.fonte
Resumindo:
Não imutável:
Imutável:
Este é um erro no Python 3 porque é imutável. E não é um erro no Python 2 porque claramente não é imutável.
fonte
A função
id()
interna retorna a identidade de um objeto como um inteiro. Este inteiro geralmente corresponde à localização do objeto na memória.Inicialmente, 'a' é armazenado no local da memória 139831803293008, pois o objeto string é imutável em python se você tentar modificar e reatribuir a referência será removida e será um ponteiro para um novo local da memória (139831803293120).
fonte
fonte
Esta imagem dá a resposta. Por favor, leia.
fonte
Devemos apenas concatenar os dois valores de string. Nunca mudamos o valor de (a). Agora, (a) representa outro bloco de memória que tem o valor "cãozinho". Porque no backend, uma variável nunca representa dois blocos de memória ao mesmo tempo. O valor de (a) antes da concatenação era "cachorro". Mas depois disso (a) representam o "cãozinho", porque agora (a) no representante de backend. o bloco que tem o valor "dogdog". E "cachorro" é representante. por (b) e "cachorro" não é contado como valor de lixo até que (b) represente o "cachorro".
A confusão é que representamos os blocos de memória (que contêm dados ou informações) no backend com o mesmo nome de variável.
fonte
Você pode tornar uma matriz numpy imutável e usar o primeiro elemento:
então:
ou
fonte