Ответ 1
В типе изменяемой последовательности Python bytearray * см. эта ссылка
Пожалуйста, знаете ли вы о библиотеке Python, которая предоставляет изменяемые строки? Google вернул на удивление мало результатов. Единственная используемая библиотека, которую я нашел, - http://code.google.com/p/gapbuffer/, которая находится в C, но я предпочел бы, чтобы она была написана на чистом Python.
Изменить: спасибо за ответы, но я после эффективной библиотеки. То есть ''.join(list)
может работать, но я надеялся на что-то более оптимизированное. Кроме того, он должен поддерживать обычные обычные строки, такие как регулярное выражение и юникод.
В типе изменяемой последовательности Python bytearray * см. эта ссылка
Это позволит вам эффективно изменять символы в строке. Хотя вы не можете изменить длину строки.
>>> 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'>)
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.
Как насчет просто подклассификации 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']