当前位置: 首页 > 后端技术 > Python

《流畅的python》读书笔记1:切片与原理

时间:2023-03-25 19:49:57 Python

本文分为以下几个部分:1:我们在什么场景下使用切片?2:实现切片的原理。基于此,我们如何实现一个支持切片操作的自定义类型呢?我们会在什么场景下使用切片呢?当我们想要拦截一段代码时,该怎么做呢?例如:list=[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0]array1=array('d',list)components=reprlib.repr(array1)#此时返回字符串:"array('d',[0.0,1.0,2.0,3.0,4.0,...])"#现在我们只需要[及其后面的字符串],这时候怎么办呢?#最笨的方法:一个一个取值:components[12],components[13].....,或者用for循环。但是python也提供了切片,方便操作:components=components[components.find('['):-1]#一行代码解决问题《流畅的python》例10.2的__repr__使用切片组合了一个New"构造函数细绳”。我们也知道切片是对象,这个可以用于什么场景呢?请看下面这段代码和注释>>>invoice="""...0....5......tan168男...guan160女..."""#上面是一个字符串,现在要取出每一行的第一段和第二段怎么办?最愚蠢的想法是按标记进行选择。>>>name=slice(0,5)>>>height=slice(5,10)>>>gender=slice(10,None)#给每个切片对象起一个名字,以便将来重用。以后直接写名字就可以了,不用写下标了。>>>list=invoice.split('\n')[2:]>>>foriteminlist:...print(item[name],item[height])...tan168guan160切片操作原理是什么?当我们调用list[0:8]时,解释器实际上将对象slice(0,8)传递给了list.__getitem__(self,slice),让我们看看Python如何改变my_seq[1:3]的语法传递给my_seq的参数.__getitem__(...):>>>MySeq类:...def__getitem__(self,index):...返回索引...>>>s=MySeq()>>>s[1]1>>>s[1:4]slice(1,4,None)>>>s[1:4:2]slice(1,4,2)>>>s[1:4:2,9](切片(1,4,2),9)>>>s[1:4:2,7:9](slice(1,4,2),slice(7,9,None))__getitem__会根据传入的数据类型。让我们自定义一个类,使其支持切片,以便更好地理解:self._components)def__repr__(self):components=reprlib.repr(self._components)components=components[components.find('['):-1]返回'Vector({})'.format(components)def__str__(self):returnstr(tuple(self))def__len__(self):returnlen(self._components)def__getitem__(self,index):returnself._components[index]执行结果如下:>>>v7=Vector(range(7))>>>v7[1:4]array('d',[1.0,2.0,3.0])》这个问题,我们拿到的切片本来应该也是一个Vector类的,但是现在是数组类型,怎么解决呢?这就要用到我们上面说的切片原理了,我们需要根据不同的类型使用不同的类型,采取不同的方法类Vector:typecode='d'def__init__(self,components):self._components=array(self.typecode,components)def__iter__(self):returniter(self._components)def__repr__(self):components=reprlib.repr(self._components)components=components[components.find('['):-1]return'Vector({})'.format(components)def__str__(self):returnstr(tuple(self))def__len__(self):returnlen(self._components)def__getitem__(self,index):cls=type(self)ifisinstance(index,slice):returncls(self._components[index])elifisinstance(index,numbers.Integral):returnself._components[index]else:msg='{cls.__name__}indicesmustbeintegers'raiseTypeError(msg.format(cls=cls))扩展思考:使用上面的方法,如何实现一个字典也可以分片?