拜托,你知道一个提供可变字符串的Python库吗?谷歌的结果令人惊讶地回归。我找到的唯一可用的库是http://code.google.com/p/gapbuffer/,它在C中,但我更喜欢用纯Python编写。
编辑:感谢您的回复,但我正在使用高效的库。也就是说,''.join(list)
可能有效,但我希望有更优化的东西。此外,它必须支持常规字符串常用的东西,如正则表达式和unicode。
答案 0 :(得分:20)
在Python中,可变序列类型为 bytearray ,请参阅this link
答案 1 :(得分:19)
这将允许您有效地更改字符串中的字符。虽然你不能改变字符串长度。
>>> 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 :(得分:12)
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,buffer或bytearray。
答案 3 :(得分:2)
如何简单地对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
。由于TypeError: sequence item n: expected string, X found
操作,其他所有内容仍然可以自由分配,但在打印时会引发string.join()
。如果这还不够好,可以轻松添加进一步的检查(也可以添加到__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']
答案 4 :(得分:1)
Python中有效的可变字符串是 arrays 。
PY3使用标准库中的array.array
的unicode字符串示例:
>>> ua = array.array('u', 'teststring12')
>>> ua[-2:] = array.array('u', '345')
>>> ua
array('u', 'teststring345')
>>> re.search('string.*', ua.tounicode()).group()
'string345'
bytearray
为字节预定义,并且在转换和兼容性方面更加自动化。
在某些情况下,您还可以考虑使用memoryview
/ buffer
,numpy
数组,mmap
和multiprocessing.shared_memory
数组。
答案 5 :(得分:1)
pypi 中的 FIFOStr 包支持模式匹配和可变字符串。这可能是也可能不是真正想要的,但它是作为串行端口模式解析器的一部分创建的(字符从左侧或右侧一次添加一个字符 - 请参阅文档)。它派生自 deque。
from fifostr import FIFOStr
myString = FIFOStr("this is a test")
myString.head(4) == "this" #true
myString[2] = 'u'
myString.head(4) == "thus" #true
(完全披露我是 FIFOstr 的作者)
答案 6 :(得分:-2)
只要这样做
string = "big"
string = list(string)
string[0] = string[0].upper()
string = "".join(string)
print(string)
'''输出'''
>大