web-dev-qa-db-ja.com

Pythonの可変文字列

Python可変文字列を提供するライブラリを知っていますか?Googleは驚くほど少数の結果を返しました。見つかった使用可能なライブラリは http://code.google.com/ p/gapbuffer / これはCで記述されていますが、純粋なPythonで書かれていることが望ましいです。

編集:応答していただきありがとうございますが、私は効率的なライブラリを求めています。つまり、''.join(list)は機能するかもしれませんが、もっと最適化されたものを望んでいました。また、正規表現やUnicodeなど、通常の文字列が行う通常の機能をサポートする必要があります。

31
Ecir Hana

In Python mutable sequence type isbytearraysee this link

20
Jason Morgan

これにより、文字列内の文字を効率的に変更できます。文字列の長さは変更できませんが。

>>> 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'>)
19
JohnMudd
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、バッファ、またはバイト配列をサブクラス化することもできます。

12
Joel Cornett

単純に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']
_

以下が修正されました。以下の更新を参照してください。

1つの(解決可能な)警告があります。各要素が実際に文字であることを(まだ)チェックしていません。少なくとも、文字列以外のすべての印刷は失敗します。ただし、これらは結合でき、次のような奇妙な状況を引き起こす可能性があります:[以下のコード例を参照]

カスタム___setitem___を使用して、CharListアイテムに長さ!= 1の文字列を割り当てると、ValueErrorが発生します。それ以外はすべて自由に割り当てることができますが、string.join()操作のために、印刷時に_TypeError: sequence item n: expected string, X found_が発生します。それで十分でない場合は、さらにチェックを簡単に追加できます(場合によっては___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']
_
2
NichtJens