Python str视图

时间:2014-11-19 09:36:40

标签: python memory python-3.x python-2.x

我的str长度大约为1GB:

>>> len(L)
1073741824

我需要从特定索引中取出许多字符串,直到字符串结束。在C中我会这样做:

char* L = ...;
char* p1 = L + start1;
char* p2 = L + start2;
...

但在Python中,切片字符串会创建一个使用更多内存的新str实例:

>>> id(L)
140613333131280
>>> p1 = L[10:]
>>> id(p1)
140612259385360

为了节省内存,我如何创建一个类似str的对象,实际上是指向原始L的指针?

修改:我们在Python 2和Python 3中有buffermemoryview,但memoryview没有显示与{{1}相同的界面}或str

bytes

2 个答案:

答案 0 :(得分:6)

memoryview类型:

>>> v = memoryview('potato')
>>> v[2]
't'
>>> v[-1]
'o'
>>> v[1:4]
<memory at 0x7ff0876fb808>
>>> v[1:4].tobytes()
'ota'

答案 1 :(得分:4)

如果您需要处理字符串,请使用迭代器实际访问数据而不复制内存中的内容

您的交易工具是itertools.teeitertools.islice

>>> L = "Random String of data"
>>> p1, p2 = tee(L)
>>> p1 = islice(p1,10,None)
>>> p2 = islice(p2,15,None)
>>> ''.join(p1) # This now creates a copy now
'ing of data'
>>> ''.join(p2) # This now creates a copy now
'f data'

这在字面意义上产生一个指针,与C / C ++不同,它只是一个前向指针/迭代器

注意当然,您需要在使用前向迭代器时进行尽职调查

  1. 在前进之前保存指针。 itertools.tee
  2. 会像p1, p_saved = tee(p1) 一样有用next(p1)
  3. 您可以读取字符''.join(p1)或字符串''.join(p1) == ''.join(p2),但由于python字符串不可变,因此每次需要字符串视图时,都会显示为副本。
  4. 由于您可以读作单个字符,因此您的所有算法都应该利用可迭代功能而不是生成字符串。例如,要比较两个迭代器,而不是比较内容all(a == b for a, b in izip(p1, p2)),您需要执行以下{{1}}