Risposte:
Non modificare le stringhe.
Lavora con loro come liste; trasformali in stringhe solo quando necessario.
>>> 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'
Le stringhe di Python sono immutabili (cioè non possono essere modificate). Ci sono molte ragioni per questo. Usa gli elenchi fino a quando non hai scelta, solo successivamente trasformali in stringhe.
MID
dovute alle sezioni:s[:index] + c + s[index+1:]
Ci sono tre modi. Per i cercatori di velocità consiglio 'Metodo 2'
Metodo 1
Dato da questa risposta
text = 'abcdefg'
new = list(text)
new[6] = 'W'
''.join(new)
Che è piuttosto lento rispetto al "Metodo 2"
timeit.timeit("text = 'abcdefg'; s = list(text); s[6] = 'W'; ''.join(s)", number=1000000)
1.0411581993103027
Metodo 2 (METODO VELOCE)
Dato da questa risposta
text = 'abcdefg'
text = text[:1] + 'Z' + text[2:]
Che è molto più veloce:
timeit.timeit("text = 'abcdefg'; text = text[:1] + 'Z' + text[2:]", number=1000000)
0.34651994705200195
Metodo 3:
Matrice di byte:
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)
due volte più lento di quello più veloce.
Le stringhe di Python sono immutabili, puoi cambiarle facendo una copia.
Il modo più semplice per fare quello che vuoi è probabilmente:
text = "Z" + text[1:]
Le text[1:]
restituisce la stringa nella text
dalla posizione 1 alla fine, posizioni contare da 0 così '1' è il secondo carattere.
modifica: è possibile utilizzare la stessa tecnica di suddivisione in stringhe per qualsiasi parte della stringa
text = text[:1] + "Z" + text[2:]
Oppure se la lettera appare solo una volta puoi usare la ricerca e sostituire la tecnica suggerita di seguito
A partire da python 2.6 e python 3 è possibile utilizzare i bytearray che sono mutabili (può essere modificato a livello di elemento a differenza delle stringhe):
s = "abcdefg"
b_s = bytearray(s)
b_s[1] = "Z"
s = str(b_s)
print s
aZcdefg
modifica: modificato da str a s
edit2: Come menzionato nei commenti l'alchimista a due bit, questo codice non funziona con Unicode.
bytearray(s)
, no bytearray(str)
. Per un altro, questo produrrà: TypeError: string argument without an encoding
. Se si specifica una codifica, si ottiene TypeError: an integer is required
. Questo è con Unicode di Python 3 o Python 2. Se lo fai in Python 2 (con una seconda riga corretta), non funzionerà con caratteri non ASCII perché potrebbero non essere solo un byte. Provalo con s = 'Héllo'
e otterrai 'He\xa9llo'
.
s = u'abcdefg'
.
Come altri hanno già detto, generalmente le stringhe di Python dovrebbero essere immutabili.
Tuttavia, se si utilizza CPython, l'implementazione su python.org, è possibile utilizzare ctypes per modificare la struttura della stringa in memoria.
Ecco un esempio in cui utilizzo la tecnica per cancellare una stringa.
Contrassegna i dati come sensibili in Python
Lo dico per completezza, e questa dovrebbe essere la tua ultima risorsa in quanto è hacker.
str
non è il tipo giusto per te. Basta non usarlo. Usa bytearray
invece qualcosa di simile . (Meglio ancora, avvolgilo in qualcosa che ti consenta di trattarlo più o meno come un dato opaco in modo da non poterne veramente recuperare uno str
da esso, per proteggerti dagli incidenti. Potrebbe esserci una libreria per quello. Nessuna idea.)
Questo codice non è mio. Non riuscivo a ricordare il modulo del sito dove l'ho preso. È interessante notare che è possibile utilizzare questo per sostituire uno o più personaggi con uno o più personaggi. Sebbene questa risposta sia molto tardi, i novizi come me (in qualsiasi momento) potrebbero trovarla utile.
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 al documento
In realtà, con le stringhe, puoi fare qualcosa del genere:
oldStr = 'Hello World!'
newStr = ''
for i in oldStr:
if 'a' < i < 'z':
newStr += chr(ord(i)-32)
else:
newStr += i
print(newStr)
'HELLO WORLD!'
Fondamentalmente, sto "aggiungendo" + "stringhe" insieme in una nuova stringa :).
se il tuo mondo è al 100% ascii/utf-8
(molti casi d'uso si adattano a quella scatola):
b = bytearray(s, 'utf-8')
# process - e.g., lowercasing:
# b[0] = b[i+1] - 32
s = str(b, 'utf-8')
python 3.7.3
Vorrei aggiungere un altro modo di cambiare un personaggio in una stringa.
>>> text = '~~~~~~~~~~~'
>>> text = text[:1] + (text[1:].replace(text[0], '+', 1))
'~+~~~~~~~~~'
Quanto è più veloce rispetto alla trasformazione della stringa in elenco e alla sostituzione del valore ith per poi ricollegarsi ?.
Elenco di approccio
>>> timeit.timeit("text = '~~~~~~~~~~~'; s = list(text); s[1] = '+'; ''.join(s)", number=1000000)
0.8268570480013295
La mia soluzione
>>> timeit.timeit("text = '~~~~~~~~~~~'; text=text[:1] + (text[1:].replace(text[0], '+', 1))", number=1000000)
0.588400217000526