Respostas:
Não modifique strings.
Trabalhe com eles como listas; transformá-los em strings somente quando necessário.
>>> s = list("Hello zorld")
>>> s
['H', 'e', 'l', 'l', 'o', ' ', 'z', 'o', 'r', 'l', 'd']
>>> s[6] = 'W'
>>> s
['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd']
>>> "".join(s)
'Hello World'
Strings Python são imutáveis (ou seja, não podem ser modificadas). Existem muitas razões para isso. Use as listas até não ter escolha, e depois transforme-as em strings.
MID
devido a fatias:s[:index] + c + s[index+1:]
Existem três maneiras. Para os que procuram velocidade, eu recomendo o "Método 2"
Método 1
Dado por esta resposta
text = 'abcdefg'
new = list(text)
new[6] = 'W'
''.join(new)
O que é bem lento em comparação com o "Método 2"
timeit.timeit("text = 'abcdefg'; s = list(text); s[6] = 'W'; ''.join(s)", number=1000000)
1.0411581993103027
Método 2 (MÉTODO RÁPIDO)
Dado por esta resposta
text = 'abcdefg'
text = text[:1] + 'Z' + text[2:]
O que é muito mais rápido:
timeit.timeit("text = 'abcdefg'; text = text[:1] + 'Z' + text[2:]", number=1000000)
0.34651994705200195
Método 3:
Matriz de bytes:
timeit.timeit("text = 'abcdefg'; s = bytearray(text); s[1] = 'Z'; str(s)", number=1000000)
1.0387420654296875
timeit.timeit("text = 'abcdefg'; s = bytearray(text); s[1] = 'Z'; str(s)", number=1000000)
duas vezes mais lento que o mais rápido.
new = text[:1] + 'Z' + text[2:]
Seqüências de caracteres Python são imutáveis, você as altera fazendo uma cópia.
A maneira mais fácil de fazer o que você quer é provavelmente:
text = "Z" + text[1:]
Os text[1:]
retornos a corda no text
da posição 1 para o final, as posições contar de 0 so '1' é o segundo personagem.
editar: você pode usar a mesma técnica de corte de cadeia para qualquer parte da cadeia
text = text[:1] + "Z" + text[2:]
Ou se a letra aparecer apenas quando você puder usar a técnica de pesquisa e substituição sugerida abaixo
Começando com o python 2.6 e python 3, você pode usar bytearrays que são mutáveis (podem ser alterados em termos de elementos, diferentemente das strings):
s = "abcdefg"
b_s = bytearray(s)
b_s[1] = "Z"
s = str(b_s)
print s
aZcdefg
edit: Alterado str para s
edit2: Como o Alquimista de dois bits mencionado nos comentários, esse código não funciona com unicode.
bytearray(s)
, não bytearray(str)
. Por outro lado, este irá produzir: TypeError: string argument without an encoding
. Se você especificar uma codificação, receberá TypeError: an integer is required
. Isso ocorre com o unicode do Python 3 ou do Python 2. Se você fizer isso no Python 2 (com uma segunda linha corrigida), ele não funcionará para caracteres não ASCII, pois eles podem não ter apenas um byte. Experimente s = 'Héllo'
e você receberá 'He\xa9llo'
.
s = u'abcdefg'
.
Como outras pessoas disseram, geralmente as seqüências de caracteres Python são imutáveis.
No entanto, se você estiver usando o CPython, a implementação em python.org, é possível usar ctypes para modificar a estrutura de strings na memória.
Aqui está um exemplo em que eu uso a técnica para limpar uma string.
Marcar dados como sensíveis em python
Menciono isso por uma questão de perfeição, e esse deve ser seu último recurso, pois é um hack.
str
não é o tipo certo para você. Só não use. Use algo como em bytearray
vez disso. (Melhor ainda, envolva-o em algo que permita tratá-lo mais ou menos como dados opacos, para que você realmente não possa recuperar um deles str
, para protegê-lo de acidentes. Pode haver uma biblioteca para isso. Não faço ideia.)
Este código não é meu. Não conseguia me lembrar do formulário do site onde o peguei. Curiosamente, você pode usar isso para substituir um caractere ou mais por um ou mais caracteres. Embora essa resposta seja muito tardia, novatos como eu (a qualquer momento) podem achar útil.
mytext = 'Hello Zorld'
mytext = mytext.replace('Z', 'W')
print mytext,
l
. mytext = mytext.replace('l', 'W')
->HeWWo Zorld
mytext = mytext.replace('l', 'W',1)
. Link para doc
Na verdade, com strings, você pode fazer algo assim:
oldStr = 'Hello World!'
newStr = ''
for i in oldStr:
if 'a' < i < 'z':
newStr += chr(ord(i)-32)
else:
newStr += i
print(newStr)
'HELLO WORLD!'
Basicamente, estou "adicionando" + "strings" em uma nova string :).
se seu mundo for 100% ascii/utf-8
(muitos casos de uso se encaixam nessa caixa):
b = bytearray(s, 'utf-8')
# process - e.g., lowercasing:
# b[0] = b[i+1] - 32
s = str(b, 'utf-8')
python 3.7.3
Gostaria de adicionar outra maneira de alterar um caractere em uma string.
>>> text = '~~~~~~~~~~~'
>>> text = text[:1] + (text[1:].replace(text[0], '+', 1))
'~+~~~~~~~~~'
Quão mais rápido é quando comparado a transformar a string em lista e substituir o i-ésimo valor e depois juntar-se novamente?
Abordagem de lista
>>> timeit.timeit("text = '~~~~~~~~~~~'; s = list(text); s[1] = '+'; ''.join(s)", number=1000000)
0.8268570480013295
Minha solução
>>> timeit.timeit("text = '~~~~~~~~~~~'; text=text[:1] + (text[1:].replace(text[0], '+', 1))", number=1000000)
0.588400217000526