46

你知道提供可变字符串的 Python 库吗?谷歌返回的结果出奇地少。我发现的唯一可用库是http://code.google.com/p/gapbuffer/,它是用 C 语言编写的,但我更希望它用纯 Python 编写。

编辑:感谢您的回复,但我想要一个高效的图书馆。也就是说,''.join(list)可能会起作用,但我希望得到更优化的东西。此外,它必须支持常规字符串的常用功能,例如 regex 和 unicode。

4

7 回答 7

28

在 Python 中,可变序列类型是字节数组,请参阅此链接

于 2012-05-13T15:01:07.877 回答
22

这将允许您有效地更改字符串中的字符。虽然你不能改变字符串的长度。

>>> 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'>)
于 2014-10-03T02:14:49.260 回答
15
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、缓冲区或字节数组。

于 2012-05-13T15:06:55.190 回答
3

简单的子类化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()操作原因,打印时会引发 a。如果这还不够好,可以轻松添加进一步的检查(可能也可以__setslice__或通过将基类切换为collections.Sequence(性能可能不同?!),参见此处

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']
于 2017-08-27T00:25:54.380 回答
2

pypi 中的FIFOStr包支持模式匹配和可变字符串。这可能是也可能不是真正想要的,但它是作为串行端口模式解析器的一部分创建的(字符一次从左侧或右侧添加一个字符 - 请参阅文档)。它源自双端队列。

from fifostr import FIFOStr

myString = FIFOStr("this is a test")
myString.head(4) == "this"  #true
myString[2] = 'u'
myString.head(4) == "thus"  #true

(完全披露我是 FIFOstr 的作者)

于 2021-08-10T00:11:16.683 回答
1

Python 中高效的可变字符串是数组array.array使用标准库的 unicode 字符串的 PY3 示例:

>>> ua = array.array('u', 'teststring12')
>>> ua[-2:] = array.array('u', '345')
>>> ua
array('u', 'teststring345')
>>> re.search('string.*', ua.tounicode()).group()
'string345'

bytearray是为字节预定义的,并且在转换和兼容性方面更加自动化。

您还可以考虑memoryview/ buffernumpy数组mmapmultiprocessing.shared_memory 某些情况。

于 2020-05-21T10:55:21.750 回答
-2

就这样做
string = "big"
string = list(string)
string[0] = string[0].upper()
string = "".join(string)
print(string)

'''输出'''
  > 大

于 2020-10-20T07:27:37.527 回答