Odpowiedzi:
Nie modyfikuj ciągów.
Pracuj z nimi jako listami; zamieniaj je w łańcuchy tylko w razie potrzeby.
>>> 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'
Ciągi w języku Python są niezmienne (tzn. Nie można ich modyfikować). Jest wiele powodów. Używaj list, dopóki nie będziesz mieć wyboru, tylko zamień je w ciągi znaków.
MID
ze względu na plasterki:s[:index] + c + s[index+1:]
Istnieją trzy sposoby. Osobom poszukującym prędkości polecam „Method 2”
Metoda 1
Biorąc pod uwagę tę odpowiedź
text = 'abcdefg'
new = list(text)
new[6] = 'W'
''.join(new)
Co jest dość wolne w porównaniu z „metodą 2”
timeit.timeit("text = 'abcdefg'; s = list(text); s[6] = 'W'; ''.join(s)", number=1000000)
1.0411581993103027
Metoda 2 (SZYBKA METODA)
Biorąc pod uwagę tę odpowiedź
text = 'abcdefg'
text = text[:1] + 'Z' + text[2:]
Co jest znacznie szybsze:
timeit.timeit("text = 'abcdefg'; text = text[:1] + 'Z' + text[2:]", number=1000000)
0.34651994705200195
Metoda 3:
Tablica bajtów:
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)
dwa razy wolniejsza niż najszybsza.
new = text[:1] + 'Z' + text[2:]
Ciągi w języku Python są niezmienne, można je zmienić, wykonując kopię.
Najłatwiejszym sposobem na zrobienie tego, co chcesz, jest prawdopodobnie:
text = "Z" + text[1:]
Do text[1:]
zwraca łańcuch w text
od pozycji 1 do końca, liczyć pozycje od 0 więc „1” to drugi znak.
edycja: Możesz użyć tej samej techniki odcinania łańcucha dla dowolnej części łańcucha
text = text[:1] + "Z" + text[2:]
Lub jeśli litera pojawia się tylko raz, możesz skorzystać z techniki wyszukiwania i zamiany zaproponowanej poniżej
Począwszy od Pythona 2.6 i Pythona 3, możesz używać bajtów, które są mutowalne (można je zmieniać w zależności od elementu w przeciwieństwie do ciągów znaków):
s = "abcdefg"
b_s = bytearray(s)
b_s[1] = "Z"
s = str(b_s)
print s
aZcdefg
edycja: Zmieniono str na s
edit2: Jak wspomniano w komentarzach Two-Bit Alchemist, ten kod nie działa z Unicode.
bytearray(s)
nie bytearray(str)
. Po drugie, to będzie produkować: TypeError: string argument without an encoding
. Jeśli określisz kodowanie, otrzymasz TypeError: an integer is required
. Tak jest w przypadku kodu Unicode Python 3 lub Python 2. Jeśli zrobisz to w Pythonie 2 (z poprawioną drugą linią), nie będzie działać dla znaków spoza ASCII, ponieważ mogą one nie być tylko jednym bajtem. Spróbuj z, s = 'Héllo'
a dostaniesz 'He\xa9llo'
.
s = u'abcdefg'
.
Jak powiedzieli inni ludzie, generalnie ciągi Pythona powinny być niezmienne.
Jeśli jednak używasz CPython, implementacji w python.org, możliwe jest użycie ctypów do modyfikacji struktury łańcucha w pamięci.
Oto przykład, w którym używam techniki do usuwania ciągu.
Oznacz dane jako wrażliwe w pythonie
Wspominam o tym ze względu na kompletność i powinno to być twoje ostateczne rozwiązanie, ponieważ jest hackerskie.
str
nie jest to odpowiedni typ dla Ciebie. Po prostu tego nie używaj. bytearray
Zamiast tego użyj czegoś takiego . (Jeszcze lepiej, zawiń go w coś, co pozwala traktować go mniej więcej jako nieprzejrzyste dane, aby naprawdę nie można byłostr
z niego odzyskać , aby uchronić Cię przed wypadkami. Może to być biblioteka. Nie ma pojęcia.)
Ten kod nie jest mój. Nie mogłem sobie przypomnieć formularza witryny, w którym go wziąłem. Co ciekawe, możesz użyć tego, aby zastąpić jedną lub więcej postaci jednym lub więcej postaciami. Chociaż ta odpowiedź jest bardzo późna, nowicjusze tacy jak ja (w każdej chwili) mogą uznać ją za przydatną.
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 do dokumentu
Właściwie za pomocą łańcuchów możesz zrobić coś takiego:
oldStr = 'Hello World!'
newStr = ''
for i in oldStr:
if 'a' < i < 'z':
newStr += chr(ord(i)-32)
else:
newStr += i
print(newStr)
'HELLO WORLD!'
Zasadniczo „dodam” ciągi „+” razem do nowego ciągu :).
jeśli twój świat jest w 100% ascii/utf-8
(wiele przypadków użycia mieści się w tym polu):
b = bytearray(s, 'utf-8')
# process - e.g., lowercasing:
# b[0] = b[i+1] - 32
s = str(b, 'utf-8')
python 3.7.3
Chciałbym dodać inny sposób zmiany znaku w ciągu.
>>> text = '~~~~~~~~~~~'
>>> text = text[:1] + (text[1:].replace(text[0], '+', 1))
'~+~~~~~~~~~'
Jak to jest szybsze w porównaniu do zamiany łańcucha na listę i zamiany i-tej wartości, a następnie ponownego przyłączenia ?.
Podejście do listy
>>> timeit.timeit("text = '~~~~~~~~~~~'; s = list(text); s[1] = '+'; ''.join(s)", number=1000000)
0.8268570480013295
Moje rozwiązanie
>>> timeit.timeit("text = '~~~~~~~~~~~'; text=text[:1] + (text[1:].replace(text[0], '+', 1))", number=1000000)
0.588400217000526