Python Slice对象到Sequence序列对象

问题背景

最近在攻Numpy包,发现以下特别让我很疑惑,因为从python基础而来,终将又回到python中去:

import numpy as np a = np.array([1,2,3,4]) b = a[1:2] c = a[1] print('the type of b is:{},value is {}'.format(type(b),b)) # print('the type of c is:{},value is {}'.format(type(c),c)) output: the type of b is:<class 'numpy.ndarray'>,value is [2] the type of c is:<class 'numpy.int64'>,value is 2
  • b、c数据类型分别为ndarray类、int类,value上b多了一个中括号;
  • 经列表进行切片(slice)以及索引以后,返回不同的对象,分别是列表 list、 integer,在经过查询python doc以后发现这其中存在slice对象 slice对象
    • Slice对象:创建方式:Slice(start,stop,step) 或者 var[start:stop:step] 中间使用冒号,代表var对象内部中在使用Slice对象;
    • 不过在此之前需要提出一点:像序列sequence(元组、列表、字符、slice)都是通过方法__getItem__方法通过整数索引对元素进行访问,slice也是如此。以下是自定义序列(当然协议实现协议还需要有__len__,不过此处用不到)。
d =slice(1,4,1) # 1 2 3 返回3个元素 a = [1,2,3,4] c = a[d] #取3个元素 #list列表的索引只能为int或slice对象 否则出现: TypeError: list indices must be integers or slices, not list c1 = a[1:4:1] #a作为列表,使用a:b:c这种索引在内部会产生像上述 同样的slice对象 print(c) # 2,3,4 print(c1) # 2,3,4 #list索引接受索引整数和slice对象时分别返回对象是integer、 list对象。这就可以解释在numpy中np.array[1:2] 与np.array[1]维度分别是 a = [1,2,3,4] b = a[1] # b 返回值:1 c = slice(1) a[c] #返回值:[1] 将slice对象c传入到a中所谓索引,返回[1] 与a[1:2]一致。

切片与__getitem__方法联系

  • [start:stop:step] 在python中就涉及到了切片操作 传递给__getitem__方法分别对应不同的参数,当索引是integer的时候,序列将索引当作元素在序列中位置,直接取数,涉及到切片的时候按照以下进行:
class Demo(): def __getitem__(self, item): return item de =Demo() de[1] # Out[3]: 1 整数索引 返回元素 de[1,2,3] # Out[4]: (1, 2, 3) 索引中存在逗号,返回元组 de[1:3:1] # Out[5]: slice(1, 3, 1) 索引中存在冒号: 返回slice对象

穿插点:slice对象、sequence对象

Slice对象:

  • 在官方定义中,Slice对象经常包含序列的一部分,这样肯定不太理解,换个说法,在方括号中 数字之间有冒号,这里面就存在切片 slice
  • 生成Slice类,slice(start,stop,step),或者slice(stop),上述例子已经给出,此处再多余说一个slice类的方法,indices(len)返回一个元组(start,stop,step)用于规整slice类中对于超出start、stop、step所定义区间的范围,换句话说超出区间的会被截掉:
slice(1,10).indices(5) 等同于 slice(1:5:1) slice(-2,None,None).indices(6) 等同于 slice(4,6,1),处理负数索引 'ABCDEFGH'[-3:20:1] 字符串总共长度只有8,索引内stop为20,超出长度,负数为逆序索引,正序索引即为长度+负数索引,step不变,所以前面切片等同于'ABCDEFGH'[5:8:1]

sequence对象

  • python中奉行一切皆对象,也存在许多鸭子类型,对于序列对象也不例外,只要实现了序列接口协议,我们也可以将其当作自定义序列对象:实现了__getitem__以及__len___
  • 当初也是在研究list[index]的时候看python发生了什么,后来了解到当使用 x[key]的时候,内部就会调用x.getitem(key)这一特殊方法,所以接下来需要去深入__getitem__ 方法
from array import array import numbers class Demo(): def __init__(self,temp): self.__temp = array.array('i',temp) #其中i作为typecode,代表初始化数组的数据类型是整型 def __getitem__(self,index): if isinstince(index,slice): #index是slice对象 return self.__class__(self.__temp[index]) elseif isinstance(index,number.integral): #索引是整数 ,至于为何使用numbers.Integral 将在下文中作出解释 return slef.__temp[index] else: msg = '{cls.__name} indices must be integers' raise TypeError(msg.format(cls=cls)) def __len__(self): return len(self.__temp) de = Demo(range(7)) de[1:3:1] # Out: <__main__.Demo at 0x10ffffd68> # 索引为slice对象的时候,返回Demo实例,无论是list还是numpy中的array,当其索引是slice的时候,返回均是其实实例(slice对象) de[slice(1,3,1)] # Out: <__main__.Demo at 0x110013ef0> # de[1] # Out: 1 #整数索引,返回对应位置元素值 de['s'] # TypeError: Demo indices must be integers #非法索引 报错

番外知识点

+上述代码中使用了isinstance,一般来说我们是检查是否存在继承关系,在查看模块number.integral以及int类源代MRO关系如下:

import numbers import inspect print(inspect.getmro(numbers.Integral)) # (<class 'numbers.Integral'>, <class 'numbers.Rational'>, <class 'numbers.Real'>, <class 'numbers.Complex'>, <class 'numbers.Number'>, <class 'object'>) print(inspect.getmro(int)) # (<class 'int'>, <class 'object'>)
  • 在模块number中的integral类属于抽象类,因为Number继承自元类ABC,在integral源代码末尾将int注册为它的虚拟子类,这样int就可以去实现integral类中所定义的方法。官方对于虚拟子类重写isinstance方法
  • 所以isinstance也不只是检查继承,还有抽象类虚拟子类之间的关系。

__EOF__

本文作者ivan09
本文链接https://www.cnblogs.com/ivan09/p/14206409.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   烦恼1234  阅读(394)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示