Переменные строки в Python

Пожалуйста, знаете ли вы о библиотеке Python, которая предоставляет изменяемые строки? Google вернул на удивление мало результатов. Единственная используемая библиотека, которую я нашел, - http://code.google.com/p/gapbuffer/, которая находится в C, но я предпочел бы, чтобы она была написана на чистом Python.

Изменить: спасибо за ответы, но я после эффективной библиотеки. То есть ''.join(list) может работать, но я надеялся на что-то более оптимизированное. Кроме того, он должен поддерживать обычные обычные строки, такие как регулярное выражение и юникод.

Ответ 1

В типе изменяемой последовательности Python bytearray * см. эта ссылка

Ответ 2

Это позволит вам эффективно изменять символы в строке. Хотя вы не можете изменить длину строки.

>>> 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'>)

Ответ 3

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.

Ответ 4

Как насчет просто подклассификации 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 (производительность может быть разной!), Cf. здесь)

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']