Ответы:
Не изменяйте строки.
Работать с ними как списками; превращайте их в струны только при необходимости.
>>> 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'
Строки Python являются неизменяемыми (то есть они не могут быть изменены). Есть много причин для этого. Используйте списки, пока у вас нет выбора, только затем превратите их в строки.
MID
из-за кусочков:s[:index] + c + s[index+1:]
Есть три способа. Для ищущих скорость я рекомендую «Метод 2»
Способ 1
Данный ответ
text = 'abcdefg'
new = list(text)
new[6] = 'W'
''.join(new)
Что довольно медленно по сравнению с «Методом 2»
timeit.timeit("text = 'abcdefg'; s = list(text); s[6] = 'W'; ''.join(s)", number=1000000)
1.0411581993103027
Метод 2 (БЫСТРЫЙ МЕТОД)
Данный ответ
text = 'abcdefg'
text = text[:1] + 'Z' + text[2:]
Который намного быстрее:
timeit.timeit("text = 'abcdefg'; text = text[:1] + 'Z' + text[2:]", number=1000000)
0.34651994705200195
Способ 3:
Байтовый массив:
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)
два раза медленнее, чем самый быстрый.
new = text[:1] + 'Z' + text[2:]
Строки Python неизменны, вы меняете их, делая копию.
Вероятно, самый простой способ сделать то, что вы хотите, это:
text = "Z" + text[1:]
В text[1:]
возвращает строку в text
от позиции 1 до конца, позиция считать от 0 , так «1» второго символ.
редактировать: вы можете использовать ту же технику нарезки строк для любой части строки
text = text[:1] + "Z" + text[2:]
Или, если буква появляется только один раз, вы можете использовать метод поиска и замены, предложенный ниже
Начиная с python 2.6 и python 3 вы можете использовать байт-массивы, которые являются изменяемыми (могут изменяться поэлементно в отличие от строк):
s = "abcdefg"
b_s = bytearray(s)
b_s[1] = "Z"
s = str(b_s)
print s
aZcdefg
редактировать: изменен str на s
edit2: Как отметил в комментариях Two-Bit Alchemist, этот код не работает с юникодом.
bytearray(s)
, а не bytearray(str)
. С другой стороны , это будет производить: TypeError: string argument without an encoding
. Если вы укажете кодировку, то вы получите TypeError: an integer is required
. Это с Python 3 или Unicode Python 2. Если вы сделаете это в Python 2 (с исправленной второй строкой), это не сработает для не-ASCII символов, потому что они могут быть не одним байтом. Попробуйте, s = 'Héllo'
и вы получите 'He\xa9llo'
.
s = u'abcdefg'
.
Как говорили другие люди, обычно строки Python должны быть неизменяемыми.
Однако, если вы используете CPython, реализацию на python.org, можно использовать ctypes для изменения строковой структуры в памяти.
Вот пример, где я использую технику, чтобы очистить строку.
Пометить данные как чувствительные в Python
Я упоминаю это для полноты картины, и это должно быть вашим последним средством, так как оно хакерское.
str
это не тот тип, который вам подходит. Просто не используйте это. Используйте что-то вроде bytearray
этого. (Еще лучше, оберните его во что-то, что позволит вам более или менее обрабатывать его как непрозрачные данные, чтобы вы действительно не могли извлечь str
из него данные, чтобы защитить вас от несчастных случаев. Для этого может быть библиотека. Не знаю.)
Этот код не мой. Я не мог вспомнить форму сайта, где я ее взял. Интересно, что вы можете использовать это, чтобы заменить одного или нескольких персонажей одним или несколькими персонажами. Хотя этот ответ очень запоздал, новички вроде меня (в любое время) могут найти его полезным.
mytext = 'Hello Zorld'
mytext = mytext.replace('Z', 'W')
print mytext,
l
. mytext = mytext.replace('l', 'W')
->HeWWo Zorld
mytext = mytext.replace('l', 'W',1)
. Ссылка на док
На самом деле, со строками вы можете сделать что-то вроде этого:
oldStr = 'Hello World!'
newStr = ''
for i in oldStr:
if 'a' < i < 'z':
newStr += chr(ord(i)-32)
else:
newStr += i
print(newStr)
'HELLO WORLD!'
По сути, я «добавляю» + «строки» вместе в новую строку :).
Я хотел бы добавить еще один способ изменения символа в строке.
>>> text = '~~~~~~~~~~~'
>>> text = text[:1] + (text[1:].replace(text[0], '+', 1))
'~+~~~~~~~~~'
Насколько быстрее это по сравнению с превращением строки в список и заменой i-го значения с последующим присоединением снова?
Список подход
>>> timeit.timeit("text = '~~~~~~~~~~~'; s = list(text); s[1] = '+'; ''.join(s)", number=1000000)
0.8268570480013295
Мое решение
>>> timeit.timeit("text = '~~~~~~~~~~~'; text=text[:1] + (text[1:].replace(text[0], '+', 1))", number=1000000)
0.588400217000526