2024-06-09 07:30:46 发布
网友
如果对Python字符串使用string^{},它将返回字符串列表。这些被拆分的子字符串是它们的父字符串部分的副本。在
有没有可能得到一些更便宜的切片对象,它只保存一个引用、偏移量和长度到被拆分的位?在
有没有可能有一些“字符串视图”来提取和处理这些子字符串,就好像它们是字符串一样,而不复制它们的字节?在
(我问,因为我有非常大的字符串,我想切片,有时内存不足;删除副本将是一个廉价的配置文件引导的胜利。)
在Python中,String对象总是指向以NUL结尾的缓冲区,因此必须复制子字符串。正如Ignacio所指出的,您可以使用buffer()来获取字符串内存的只读视图。但是,buffer()内置函数已经被更通用的^{}对象所取代,这些对象在Python2.7和3.x中可用(buffer()在Python3.x中消失了)。在
buffer()
s = "abcd" * 50 view = memoryview(s) subview = view[10:20] print subview.tobytes()
这个密码打印出来了
一旦您调用tobytes(),就会创建一个字符串的副本,但是在对旧的buffer对象进行切片时,会出现与Ignacio的答案相同的情况。在
tobytes()
buffer
buffer将为您提供字符串的只读视图。在
>>> s = 'abcdefghijklmnopqrstuvwxyz' >>> b = buffer(s, 2, 10) >>> b <read-only buffer for 0x7f935ee75d70, size 10, offset 2 at 0x7f935ee5a8f0> >>> b[:] 'cdefghijkl'
这是我想出的一个快速的类似字符串的缓冲区包装器;我可以用它来代替传统的字符串,而不需要更改预期使用字符串的代码。在
class StringView: def __init__(self,s,start=0,size=sys.maxint): self.s, self.start, self.stop = s, start, min(start+size,len(s)) self.size = self.stop - self.start self._buf = buffer(s,start,self.size) def find(self,sub,start=0,stop=None): assert start >= 0, start assert (stop is None) or (stop <= self.size), stop ofs = self.s.find(sub,self.start+start,self.stop if (stop is None) else (self.start+stop)) if ofs != -1: ofs -= self.start return ofs def split(self,sep=None,maxsplit=sys.maxint): assert maxsplit > 0, maxsplit ret = [] if sep is None: #whitespace logic pos = [self.start,self.start] # start and stop def eat(whitespace=False): while (pos[1] < self.stop) and (whitespace == (ord(self.s[pos[1]])<=32)): pos[1] += 1 def eat_whitespace(): eat(True) pos[0] = pos[1] eat_whitespace() while pos[1] < self.stop: eat() ret.append(self.__class__(self.s,pos[0],pos[1]-pos[0])) eat_whitespace() if len(ret) == maxsplit: ret.append(self.__class__(self.s,pos[1])) break else: start = stop = 0 while len(ret) < maxsplit: stop = self.find(sep,start) if -1 == stop: break ret.append(self.__class__(self.s,self.start+start,stop-start)) start = stop + len(sep) ret.append(self.__class__(self.s,self.start+start,self.size-start)) return ret def split_str(self,sep=None,maxsplit=sys.maxint): "if you really want strings and not views" return [str(sub) for sub in self.split(sep,maxsplit)] def __cmp__(self,s): if isinstance(s,self.__class__): return cmp(self._buf,s._buf) assert isinstance(s,str), type(s) return cmp(self._buf,s) def __len__(self): return self.size def __str__(self): return str(self._buf) def __repr__(self): return "'%s'"%self._buf if __name__=="__main__": test_str = " this: is: a: te:st str:ing :" test = Envelope.StringView(test_str) print "find('is')" print "\t",test_str.find("is") print "\t",test.find("is") print "find('is',4):" print "\t",test_str.find("is",4) print "\t",test.find("is",4) print "find('is',4,7):" print "\t",test_str.find("is",4,7) print "\t",test.find("is",4,7) print "split():" print "\t",test_str.split() print "\t",test.split() print "split(None,2):" print "\t",test_str.split(None,2) print "\t",test.split(None,2) print "split(':'):" print "\t",test_str.split(":") print "\t",test.split(":") print "split('x'):" print "\t",test_str.split("x") print "\t",test.split("x") print "''.split('x'):" print "\t","".split("x") print "\t",Envelope.StringView("").split("x")
在Python中,String对象总是指向以NUL结尾的缓冲区,因此必须复制子字符串。正如Ignacio所指出的,您可以使用} 对象所取代,这些对象在Python2.7和3.x中可用(
buffer()
来获取字符串内存的只读视图。但是,buffer()
内置函数已经被更通用的^{buffer()
在Python3.x中消失了)。在这个密码打印出来了
^{pr2}$一旦您调用
tobytes()
,就会创建一个字符串的副本,但是在对旧的buffer
对象进行切片时,会出现与Ignacio的答案相同的情况。在buffer
将为您提供字符串的只读视图。在这是我想出的一个快速的类似字符串的缓冲区包装器;我可以用它来代替传统的字符串,而不需要更改预期使用字符串的代码。在
相关问题 更多 >
编程相关推荐