Изменчивые строки в Python

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

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

 Aaron Yodaiken13 мая 2012 г., 16:49
Списки работают очень хорошо для этой цели.
 chuwy29 окт. 2013 г., 14:59
@ BasicWolf может быть для эффективной замены памяти символов внутри строки? Мы избегаем создания копии строки.
 Zaur Nasibov13 мая 2012 г., 17:53
Не могли бы вы объяснить, зачем вам изменяемые строки? Какой вариант использования?
 digEmAll13 мая 2012 г., 17:00
Несколько ссылок: LINK1, LINK2
 Zaur Nasibov29 окт. 2013 г., 15:12
@ chuwy Ну, для этих целей есть байтовый массив. Строка в Python априори не является «эффективной для памяти» последовательностью, но скорее эффективной для параллелизма. Учтите это: вы всегда можете быть уверены, что независимо от того, какая операция модификации строки на исходной строке не повлияет на нее. Таким образом, нет проблем с параллелизмом, безопасностью потоков и т. Д.

Ответы на вопрос(4)

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.

 Chiel ten Brinke20 авг. 2014 г., 19:35
Исправление: регулярное выражение иfind работает только с исходной строкой. Модификации сделаны через__setitem__ игнорируются. Есть ли способ использовать регулярные выражения в MutableStrings?
 Chiel ten Brinke20 авг. 2014 г., 19:28
Чтобы иметь возможность использовать регулярные выражения и строковые методы, такие какfind вам нужно подкласс отstr вместо тогоobject.
 Chiel ten Brinke20 авг. 2014 г., 20:02
Но тогда вы можете использовать обычную строку. Я хочу / должен воспользоваться изменчивостью.
 Joel Cornett20 авг. 2014 г., 19:46
Ты можешь сделатьre.match(expression, repr(mutable_string))

изменить длину строки.

>>> 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'>)
 ivan_pozdeev18 янв. 2018 г., 17:32
ИМЕЙТЕ В ВИД что буфер включает терминатор в свой сообщаемыйlen(). Это ломает ломтики с отрицательными индексами если вы не добавите лишний-1 каждому отрицательному индексу. (Для буферов Юникода это-1 тоже потому чтоlen и индексы срезов для этих типов в символах.)

ByteArray видетьэта ссылк

 Marcin13 мая 2012 г., 17:13
Буферы только для чтения.
 freakish16 дек. 2014 г., 13:34
bytearray, как видно из названия, это массив байтов. Строки - это не последовательности байтов, а последовательности групп байтов. То есть это верно только для строк ASCII, но не для юникода в целом. -1.
 Jason Morgan13 мая 2012 г., 18:16
Спасибо Марсину, показывает, как часто я использую буферы ...
 jonathanrocher06 мар. 2014 г., 00:57
Я не уверен, на что ссылается @Marcin, потому что bytearrays позволяет вам присвоить новое значение срезу bytearray.
 robert17 нояб. 2014 г., 10:41
Это должен быть «правильный» ответ. Слишком много баловства по поводу участия в нынешнем голосовани

Как насчет простого подкласса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 (производительность может отличаться ?!), ср.Во)

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

Ваш ответ на вопрос