3

Pythonに文字列my_stringがあり、次のようにトークン化するとしsome_patternます。

match.re.search(some_pattern, my_string)
string_1 = match.group(1)
string_2 = match.group(2)
....

string_1部分文字列のstring_2(「深い」) コピーmy_stringまたはメモリ内の同じ場所への参照ですか? の文字の完全なコピー用にメモリを割り当てstring_1ますか?string_2my_string

文字列の不変性について質問しているわけではないことに注意してください。my_string非常に長い場合、文字列をトークン化することでメモリ内のヒットが何であるかを知りたいです。

再利用されるメモリの量を正確に知る必要はありませんが、文字列のトークン化によってメモリが重複するかどうかを知ることは確かに役立ちます。

4

4 に答える 4

3

Python 2.7.3 ソース コードを見ると、文字列のスライスを取得すると、文字データのコピーが作成されます。

Objects/stringobject.c:

string_slice()次の関数を呼び出しますPyString_FromStringAndSize():

/* Inline PyObject_NewVar */
op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + size);
if (op == NULL)
    return PyErr_NoMemory();
PyObject_INIT_VAR(op, &PyString_Type, size);
op->ob_shash = -1;
op->ob_sstate = SSTATE_NOT_INTERNED;
if (str != NULL)
    Py_MEMCPY(op->ob_sval, str, size);
op->ob_sval[size] = '\0';

ここで、strは文字データへのポインタで、sizeは長さです。malloc と memcpy に注意してください。

異なる Python 実装 (実際には CPython の異なるバージョン) は、異なる動作をする可能性があります。たとえば、Jython はおそらくjava.lang.Stringコピーを作成しない を使用します。

于 2012-12-04T19:38:07.037 に答える
1

Pythonでは文字列は不変であるため、部分文字列は新しいオブジェクトにすぎません。

In [7]: str="foobar"

In [8]: id(str)
Out[8]: 140976032

In [10]: id(str[:4])
Out[10]: 141060224

返される部分文字列オブジェクトが元の文字列オブジェクトと同じである唯一のケースは、string==substring

In [16]: foo="foobar"

In [17]: id(foo)
Out[17]: 140976032

In [18]: id(foo[:])
Out[18]: 140976032

In [19]: foo="foobar"*10000   # huge string

In [20]: id(foo)
Out[20]: 141606344

In [21]: id(foo[:])
Out[21]: 141606344
于 2012-12-04T19:22:53.190 に答える
1

Python文字列は不変であるため、この場合の区別はそれほど意味がありませんが、コピーです。にできることはなくstring_1string_2の内容に影響を与えmy_stringます。

于 2012-12-04T19:23:02.510 に答える
0

それがあまり役に立たないか、質問に答えるかどうかはわかりませんが、必要finditerに応じて元の文字列を使用してスライスすることができます...

>>> import re
>>> string = 'abcdefhijkl'
>>> matches = list(re.finditer('.' , string))
>>> dir(matches[0])
['__class__', '__copy__', '__deepcopy__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'end', 'endpos', 'expand', 'group', 'groupdict', 'groups', 'lastgroup', 'lastindex', 'pos', 're', 'regs', 'span', 'start', 'string']
>>> matches[0].span()
(0, 1)

そしてそこから…

于 2012-12-04T19:40:22.787 に答える