2012-05-13 21 views
24

請問,你知道提供可變字符串的Python庫嗎?谷歌迴歸令人驚訝的結果很少。我找到的唯一可用的庫是http://code.google.com/p/gapbuffer/,它是用C語言編寫的,但我更喜歡它是用純Python編寫的。Python中的可變字符串

編輯:感謝您的回覆,但我後有效的圖書館。也就是說,''.join(list)可能會工作,但我希望有更優化的東西。另外,它必須支持通常的東西,比如正則表達式和unicode。

+5

列出工作得很好此目的。 –

+0

有幾個鏈接:[LINK1](http://mail.python.org/pipermail/tutor/2003-August/024485.html),[LINK2](http://www.skymind.com/~ocrow/ python_string /) – digEmAll

+4

你能解釋一下,你爲什麼需要可變字符串?什麼是用例? –

回答

19

在Python可變的序列類型爲字節組看到this link

+2

緩衝區是隻讀的。 – Marcin

+1

感謝Marcin,顯示了我使用緩衝區的頻率...... –

+0

我不確定@Marcin所指的是什麼,因爲bytearrays允許您爲字節數組的片段分配一個新值。 – jonathanrocher

11
class MutableString(object): 
    def __init__(self, data): 
     self.data = list(data) 
    def __repr__(self): 
     return "".join(self.data) 
    def __setitem__(self, index, value): 
     self.data[index] = value 
    def __getitem__(self, index): 
     if type(index) == slice: 
      return "".join(self.data[index]) 
     return self.data[index] 
    def __delitem__(self, index): 
     del self.data[index] 
    def __add__(self, other): 
     self.data.extend(list(other)) 
    def __len__(self): 
     return len(self.data) 

... 等等,等等。

您也可以繼承StringIO,緩衝區或bytearray。

+0

爲了能夠像'find'一樣使用正則表達式和字符串方法,您需要從'str'而不是'object'的子類。 –

+0

糾錯:正則表達式和'find'只對原始字符串有效。通過'__setitem__'所做的修改無視。有沒有辦法在MutableStrings上使用正則表達式? –

+0

你可以做're.match(表達式,repr(mutable_string))' –

15

這將允許您有效地更改字符串中的字符。雖然你不能改變字符串的長度。

>>> import ctypes 

>>> a = 'abcdefghijklmn' 
>>> mutable = ctypes.create_string_buffer(a) 
>>> mutable[5:10] = ''.join(reversed(list(mutable[5:10].upper()))) 
>>> a = mutable.value 
>>> print `a, type(a)` 
('abcdeJIHGFklmn', <type 'str'>) 
+2

** BE WARNED **緩衝區將終止符包含到其所報告的「len()」中。 **除非您爲每個負向索引添加一個額外的「-1」,否則這將斷開帶負向索引的切片。 (對於unicode緩衝區,它也是'-1',因爲這些類型的len和slice索引都是字符。) –

1

如何簡單地進行子分類list(Python中可變性的主要例子)?

class CharList(list): 

    def __init__(self, s): 
     list.__init__(self, s) 

    @property 
    def list(self): 
     return list(self) 

    @property 
    def string(self): 
     return "".join(self) 

    def __setitem__(self, key, value): 
     if isinstance(key, int) and len(value) != 1: 
      cls = type(self).__name__ 
      raise ValueError("attempt to assign sequence of size {} to {} item of size 1".format(len(value), cls)) 
     super(CharList, self).__setitem__(key, value) 

    def __str__(self): 
     return self.string 

    def __repr__(self): 
     cls = type(self).__name__ 
     return "{}(\'{}\')".format(cls, self.string) 

這隻會將列表連接回字符串,如果您要打印它或主動詢問字符串表示形式。 突變和擴展是微不足道的,用戶知道如何做,因爲它只是一個列表。

實例:

s = "te_st" 
c = CharList(s) 
c[1:3] = "oa" 
c += "er" 
print C# prints "toaster" 
print c.list # prints ['t', 'o', 'a', 's', 't', 'e', 'r'] 

以下是固定的,見下文更新。

有一個(可解決的)警告:沒有檢查(但)每個元素確實是一個字符。除了字符串以外,它至少會失敗打印。然而,那些可被連接,並且可能導致這樣的怪異的情況:[見下面的代碼示例]

通過自定義__setitem__,分配長度的串= 1到CharList項將提高一個ValueError!。所有其他項目仍可以自由分配,但由於string.join()操作,打印時將增加TypeError: sequence item n: expected string, X found。如果這還不夠好,進一步的檢查可以很容易地添加(可能也__setslice__或基類轉換到collections.Sequence(性能可能會有所不同?!),參見here

s = "test" 
c = CharList(s) 
c[1] = "oa" 
# with custom __setitem__ a ValueError is raised here! 
# without custom __setitem__, we could go on: 
c += "er" 
print C# prints "toaster" 
# this looks right until here, but: 
print c.list # prints ['t', 'oa', 's', 't', 'e', 'r']