Відповіді:
Не змінюйте рядки.
Робота з ними як списки; перетворюйте їх у рядки лише за потреби.
>>> 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: Як зазначено у коментарях двобітний алхімік, цей код не працює з unicode.
bytearray(s)
, ні bytearray(str)
. З іншого боку , це буде виробляти: TypeError: string argument without an encoding
. Якщо ви вказали кодування, то отримаєте TypeError: an integer is required
. Це з унікодом Python 3 або 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)
. Посилання на doc
Насправді за допомогою рядків ви можете зробити щось подібне:
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