2010-08-11 33 views
16

在Python中,字符串是不可變的。Python中的'就地'字符串修改

什麼是標準習慣用法逐個字符地穿過字符串並修改它?

我能想到的唯一方法是與加入結果字符串相關的一些真正晦澀的黑客行爲。

-

在C:

for(int i = 0; i < strlen(s); i++) 
{ 
    s[i] = F(s[i]); 
} 

這是超級表現,說我在做什麼。這是我正在尋找的。

+0

我猜,因爲它們是不可變的,你不能「修改「...你的意思是構造一個新的字符串char-by-char? – 2010-08-12 00:02:51

+0

這真的很少見。你可以給出一個上下文或用例來做到這一點? – 2010-08-12 00:21:14

+0

向消息添加噪音以進行測試。 – 2010-08-12 00:22:43

回答

1

字符串是可迭代的,可以像列表一樣遍歷。字符串也有一些基本的方法,如.replace()這可能是你正在尋找的。所有字符串方法都會返回一個新字符因此,不要修改字符串,而只需替換其現有值。

>>> mystring = 'robot drama' 
>>> mystring = mystring.replace('r', 'g') 
>>> mystring 
'gobot dgama' 
+0

字符串*是不可變的,不能由成員分配。 – 2010-08-11 23:58:22

+0

正確。所有字符串操作都會返回輸入字符串的副本。但是,變量名不是不可變的,所以通過將字符串操作重新分配給相同的變量名稱,可以有效地「改變」字符串。 – jathanism 2010-08-12 00:00:52

+0

「如果用戶可以使用切片符號霧就地調整:'myStr [0:3] [:] = 1,則在不改變其長度的情況下,它仍然很有用。 'new''「.replace(」g「,」r「) – CoDEmanX 2015-08-20 20:00:48

1
>>> mystring = "Th1s 1s my str1ng" 
>>> mystring.replace("1", "i") 
'This is my string' 

如果你想保存這一點,你就必須mystring = mystring.replace("1", "i")字符串。這是因爲在Python中字符串是不可變的。

+0

1:不要使用」字符串「作爲變量名稱。 2:那不會修改變量。 – bstpierre 2010-08-11 23:58:13

+0

不按索引選擇並修改它。 – 2010-08-12 00:00:51

+0

@bstpierre:你走了。 :) – 2010-08-12 00:01:14

1

string.translate可能是您接下來最接近的功能。

+0

有趣的功能 - 但我要找的是能夠在給定索引處進行調整(或返回給定索引已修改的字符串)。 – 2010-08-12 00:01:35

+0

不需要從字符串導入,'str'對象具有'translate'方法。使用'string'模塊中的'maketrans'通常很方便,儘管 – 2010-08-12 00:16:04

15

不要使用一個字符串,用的東西可變ByteArray等:在

#!/usr/bin/python 

s = bytearray("my dog has fleas") 
for n in xrange(len(s)): 
    s[n] = chr(s[n]).upper() 
print s 

結果:

MY DOG HAS FLEAS 

編輯:

由於這是一個bytearray,你是不是(必然)與人物一起工作。您正在使用字節。因此,這也工作:

s = bytearray("\x81\x82\x83") 
for n in xrange(len(s)): 
    s[n] = s[n] + 1 
print repr(s) 

給出:

bytearray(b'\x82\x83\x84') 

如果你想在一個Unicode字符串修改的字符,你也許想memoryview工作,雖然不直接支持Unicode 。

+2

它們不是字符,但是隻是字節。僅適用於ASCII,不適用於Unicode。 – 2010-08-12 00:20:26

+2

適用於有效*字節*,不僅僅是ASCII。 – bstpierre 2010-08-12 00:30:40

0
def modifyIdx(s, idx, newchar): 
    return s[:idx] + newchar + s[idx+1:] 
2

將特定字符分配給字符串中的特定索引並不是特別常見的操作,因此如果您發現自己需要這樣做,請考慮是否有更好的方法來完成任務。但是,如果你確實需要,最可能最標準的方法是將字符串轉換爲列表,進行修改,然後將其轉換回字符串。

s = 'abcdefgh' 
l = list(s) 
l[3] = 'r' 
s2 = ''.join(l) 

編輯:,張貼在bstpierre的回答,bytearray可能是更好的完成這個任務比list,只要你不Unicode字符串的工作。

s = 'abcdefgh' 
b = bytearray(s) 
b[3] = 'r' 
s2 = str(b) 
+1

如果你使用多字節字符串,你最好小心不要把一個編碼的字符切碎! – 2010-08-12 00:09:34

0

如果我需要做這樣的事情,我只是將它轉換爲一個可變的列表

例如......(雖然這將是更容易使用排序(見第二個例子))

>>> s = "abcdfe" 
>>> s = list(s) 
>>> s[4] = "e" 
>>> s[5] = "f" 
>>> s = ''.join(s) 
>>> print s 
abcdef 
>>> 
# second example 
>>> s.sort() 
>>> s = ''.join(s) 
9

可以使用UserString模塊: - 「」

>>> import UserString 
... s = UserString.MutableString('Python') 
... print s 
Python 
>>> s[0] = 'c' 
>>> print s 
cython 
+5

請注意,MutableString在Python 2.6中被棄用,並在Python 3中被移除 - https://docs.python.org/2/library/userdict.html#UserString.MutableString – msanders 2014-12-08 15:28:54

1

下面是一個使用轉換切換的例子 「」 與和大寫「A」 S

>>> from string import maketrans 
>>> trans_table = maketrans(".-a","-.A") 
>>> "foo-bar.".translate(trans_table) 
'foo.bAr-' 

這是非常有效的翻轉,以字節數組,並回來,如果你需要做的僅僅單個字符替換

15
你的C

Python的模擬:

for(int i = 0; i < strlen(s); i++) 
{ 
    s[i] = F(s[i]); 
} 

是:

s = "".join(F(c) for c in s) 

這也是非常傳神。它確切地說明發生了什麼,但是以功能性風格而不是程序性風格。

+0

有趣的;我有點喜歡它,除了空字符串。雖然可能和我一樣好。 – 2010-08-12 00:35:03

+1

C對我來說很重要的一點就是它在原地工作。 – 2010-08-12 07:33:20

+1

@Joe Koberg:Python的一個重要部分是它更短,更清晰。 「就地」是有限制的,因爲你不能讓字符串更長。 – 2010-08-12 10:12:02

7

我想說的最Python的方式是使用map()

s = map(func, s) # func has been applied to every character in s 

這是寫作的等效:

s = "".join(func(c) for c in s) 
+3

小修正/點:仍然需要重新加入返回的列表(在Py3 +中的/ iter/map-obj)。所以上面應該是: 's =「」.join(map(func,s))' – pythonlarry 2013-04-03 20:54:49