【数据结构实践】手把手带你实现 Python 自定义数组

简介: 无论是任何语言,数组或者类似数组的数据结构永远是计算机编程语言不可或缺的基本数据结构,有了数组的存在更有利于我们的程序对数据的存储和操作.本文将从面向对象的入手,实现自定义数组类,实现数组的基本操作和运算等功能1、数组(Array)是有序的元素序列。若将有限个类型相同的变量的集合命名,那么这个名称为数组名。2、组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。3、用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按有序的形式组织起来的一种形式。这些有序排列的同类数据元素的集合称为数组。也就是说数组是存储相同类型数据

引言


无论是任何语言,数组或者类似数组的数据结构永远是计算机编程语言不可或缺的基本数据结构,有了数组的存在更有利于我们的程序对数据的存储和操作.本文将从面向对象的入手,实现自定义数组类,实现数组的基本操作和运算等功能


数组的定义


1、数组(Array)是有序的元素序列。若将有限个类型相同的变量的集合命名,那么这个名称为数组名。

2、组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。

3、用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按有序的形式组织起来的一种形式。这些有序排列的同类数据元素的集合称为数组。也就是说数组是存储相同类型数据的集合


什么是面向对象


面向对象是一种软件开发方法,面向对象的概念和应用已经超越了程序设计和软件开发。面向对象中的对象,通常是指客观世界中存在的对象,这个对象具有唯一性,对象之间各不相同,各有各的特点,每一一个对象都有运动的规律和内部状态。对象与对象之间是可以相互联系、相互作用的。另外,对象也可以是一个抽象的事物。

1、对象( Object): -一个抽象概念,表示任意存在的事物。现实世界中,随处可见的一一种事物就是对象,对象是事物存在的实体。对象通常被划分为两个部分,即静态部分与动态部分。 静态部分通常被称为这个对象的属性,任何对象都具有自身属性,这些属性不仅是客观存在的。而且是不能被忽略的,如人的姓名,年龄等等。动态部分指的是对象的行为,即对象执行的动作,如人可以跑步。

2、类(Class):封装对象的属性和行为的获体。反过来说,具有相同属性和行为的一类实体被称为类。


Python中类的定义如下:

classClassName:#类名使用大驼峰法,即首字母大写#类的语句块如类的成员属性...
类的方法...

当我们创建完类之后,接着就是类的使用,使用前需要对类进行实例化


比如有个Dog类

classDog:
def__init__(self, name):
self.name=name# 类的实例化如下d1=Dog("小北")


面向对象程序设计的特点:封装、继承和多态


封装:面向对象编程的核心,也是将对象的属性和行为封装起来的载体。类通常会对客尸隐臧其实现细节,这就是封装的思想。封装通过限制只有特定类的对象,访问这一 特定类的成员,而它们通常利用接口实现消息的传人和传出。采用封装思想保证了类的内部数据结构的完整性,使用该类的用户不能直接看到类中的数据结构,而只能执行类允许公开的数据,这样就可以避免外部对内部数据的影响,提高了程序的可维护性。

继承:在某种情况下,一个类会有子类,子类比原本的类要更加具体化。例如,犬这个类会有它的子类--拉布拉多犬,猎犬和泰迪犬等。“小北”可能就是哈士奇犬的一个实例。 子类会继承父类的属性和行为,并且也包含它们自己的特有属性。我们假设犬类有一个行为叫作吠叫,还有一一个属性叫作毛色,它的子类会继承这些行为和属性。综上所述,继承是实现重复利用的重要手段, 子类通过继承, 复用了父类的实现和行为,同时又添加了子类特有的属性和行为。


多态:由继承产生的不同的类,其对象对同一消息会做出不同的响应。子类继承父类特征的同时,也具备了自己的特征,并且能够实现不同的效果,这就是多态化结果。

这里只是简单唠唠面向对象的基本概念。我之前写过的一篇文章《梦回战国,领略两千多年前公孙龙如何将面向对象运用得炉火纯青》有关于面向对象的详细介绍,感兴趣的同学可参考参考。


自定义数组的实现步骤


网络异常,图片无法展示
|


使用python实现自定义数组,以及实现数组中的各种运算:

  1. 保证输入值为数字元素,通过isinstance()函数判断数据类型
  2. 初始化__init__函数,对输入的数据进行存储
  3. 重构数组的运算方法
  4. 添加数组类的类方法


代码实现


创建MyNArrays类,以及定义元素类过滤方法

classMyNArrays:
#过滤非数字类型的元素def___isNumber(self, n):
ifnotisinstance(n,(int,float,complex)):
returnFalsereturnTrue#类属性等初始化def__init__(self,*args):
ifnotargs:
self.__value= []
else:
forarginargs:
ifnotself.___isNumber(arg):
print('All elements must be numbers')
returnself.__value=list(args)
@propertydefgetValue(self):
returnself.__value#析构函数,释放内部封装的列表def__del__(self):
delself.__value#重载运算符+def__add__(self, other):
#数组中每个元素都与数字other相加,或者两个数组相加,会得到一个新数组ifself.___isNumber(other):
#数组与数字other相加b=MyNArrays()
b.__value= [item+otherforiteminself.__value]
returnbelifisinstance(other,MyNArrays):
#两个数组对应元素相加if (len(other.__value) ==len(self.__value)):
c=MyNArrays()
c.__value= [i+jfori,jinzip(self.__value,other.__value)]
returncelse:
print('Lenght no equal')
else:
print('Not supported')
#重载运算符-def__sub__(self, other):
# 数组元素与数字other做减法,得到一个新数组pass#重载运算符*def__mul__(self, other):
#数组元素与数字other做乘法,或者两个数组相乘,得到一个新数组passdef__truediv__(self, other):
passdef__floordiv__(self, other):
passdef__pow__(self, power, modulo=None):
passdef__mod__(self, other):
pass#重载数组len,支持对象直接使用len()方法def__len__(self):
returnlen(self.__value)
#支持使用print()函数查看对象的值def__str__(self):
returnstr(self.__value)
def__contains__(self, n):
ifninself.__value:
returnTruereturnFalsedefdot(self,v):
ifnotisinstance(v,MyNArrays):
print('must be an instance of MyNArrays.')
returniflen(v)!=len(self.__value):
print('size must be equal.')
returnreturnsum([i*jfori,jinzip(self.__value,v.__value)])
#让本类具有修改数组元素的功能def__setitem__(self, key, value):
length=len(self.__value)
ifisinstance(key,int) and0<=key<length:
self.__value[key]=valueelse:
return'index error'#获取数组元素   def__getitem__(self, key):
length=len(self.__value)
ifisinstance(key, int) and0<=key<length:
returnself.__value[key]
else:
return'index error'#向数组中添加元素   defappend(self,n):
ifisinstance(n,(int,float)):
self.__value.append(n)
else:
print('isinstance error')
def__repr__(self):
returnrepr(self.__value)


注:重载运算中用到zip()函数用于将可迭代对象作为参数,将对象中对应的元素打包成元组,然后返回由这些元组组成的列表


完成了自定义数组类的定义.接下来就是对类的调用.是骡子是马拉出来溜溜


创建数组:

a=MyNArrays(1,2,3,4,5,6)
b=MyNArrays(7,8,9,10,11,12)
print('数组a:',a)
print('数组b:',b)


执行结果:

数组a: [1, 2, 3, 4, 5, 6]
数组b: [7, 8, 9, 10, 11, 12]


数组的运算:

print('a+b:',a+b)
print('a和b的内积为:', a.dot(b))

执行结果:

a+b: [8, 10, 12, 14, 16, 18]
a和b的内积为: 217


数组的增删改查操作

print('2是否为a的元素:',2ina)
a.append(17)
print('a添加元素17:',a)
print('查看a的第3各元素值:',a[2])
a[6]=15print('修改最后一项值为15:',a)


执行结果:

2是否为a的元素: True
a添加元素17: [1, 2, 3, 4, 5, 6, 17]
查看a的第3各元素值: 3
修改最后一项值为15: [1, 2, 3, 4, 5, 6, 15]
目录
相关文章
|
1月前
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
142 77
|
16天前
|
存储 人工智能 算法
C 408—《数据结构》算法题基础篇—数组(通俗易懂)
408考研——《数据结构》算法题基础篇之数组。(408算法题的入门)
58 23
|
1月前
|
存储 C++
【C++数据结构——树】哈夫曼树(头歌实践教学平台习题) 【合集】
【数据结构——树】哈夫曼树(头歌实践教学平台习题)【合集】目录 任务描述 相关知识 测试说明 我的通关代码: 测试结果:任务描述 本关任务:编写一个程序构建哈夫曼树和生成哈夫曼编码。 相关知识 为了完成本关任务,你需要掌握: 1.如何构建哈夫曼树, 2.如何生成哈夫曼编码。 测试说明 平台会对你编写的代码进行测试: 测试输入: 1192677541518462450242195190181174157138124123 (用户分别输入所列单词的频度) 预
61 14
【C++数据结构——树】哈夫曼树(头歌实践教学平台习题) 【合集】
|
1月前
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
44 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
|
1月前
|
算法 C++
【C++数据结构——查找】二叉排序树(头歌实践教学平台习题)【合集】
【数据结构——查找】二叉排序树(头歌实践教学平台习题)【合集】 目录 任务描述 相关知识 测试说明 我的通关代码: 测试结果: 任务描述 本关任务:实现二叉排序树的基本算法。 相关知识 为了完成本关任务,你需要掌握:二叉树的创建、查找和删除算法。具体如下: (1)由关键字序列(4,9,0,1,8,6,3,5,2,7)创建一棵二叉排序树bt并以括号表示法输出。 (2)判断bt是否为一棵二叉排序树。 (3)采用递归方法查找关键字为6的结点,并输出其查找路径。 (4)分别删除bt中关键
53 11
【C++数据结构——查找】二叉排序树(头歌实践教学平台习题)【合集】
|
26天前
|
数据挖掘 数据处理 开发者
Python3 自定义排序详解:方法与示例
Python的排序功能强大且灵活,主要通过`sorted()`函数和列表的`sort()`方法实现。两者均支持`key`参数自定义排序规则。本文详细介绍了基础排序、按字符串长度或元组元素排序、降序排序、多条件排序及使用`lambda`表达式和`functools.cmp_to_key`进行复杂排序。通过示例展示了如何对简单数据类型、字典、类对象及复杂数据结构(如列车信息)进行排序。掌握这些技巧可以显著提升数据处理能力,为编程提供更强大的支持。
32 10
|
1月前
|
Java C++
【C++数据结构——树】二叉树的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现二叉树的基本运算。​ 相关知识 创建二叉树 销毁二叉树 查找结点 求二叉树的高度 输出二叉树 //二叉树节点结构体定义 structTreeNode{ intval; TreeNode*left; TreeNode*right; TreeNode(intx):val(x),left(NULL),right(NULL){} }; 创建二叉树 //创建二叉树函数(简单示例,手动构建) TreeNode*create
48 12
|
1月前
|
C++
【C++数据结构——树】二叉树的性质(头歌实践教学平台习题)【合集】
本文档介绍了如何根据二叉树的括号表示串创建二叉树,并计算其结点个数、叶子结点个数、某结点的层次和二叉树的宽度。主要内容包括: 1. **定义二叉树节点结构体**:定义了包含节点值、左子节点指针和右子节点指针的结构体。 2. **实现构建二叉树的函数**:通过解析括号表示串,递归地构建二叉树的各个节点及其子树。 3. **使用示例**:展示了如何调用 `buildTree` 函数构建二叉树并进行简单验证。 4. **计算二叉树属性**: - 计算二叉树节点个数。 - 计算二叉树叶子节点个数。 - 计算某节点的层次。 - 计算二叉树的宽度。 最后,提供了测试说明及通关代
46 10
|
1月前
|
算法 C++
【C++数据结构——图】最小生成树(头歌实践教学平台习题) 【合集】
【数据结构——图】最小生成树(头歌实践教学平台习题)目录 任务描述 相关知识 测试说明 我的通关代码: 测试结果:【合集】任务描述 本关任务:编写一个程序求图的最小生成树。相关知识 为了完成本关任务,你需要掌握:1.建立邻接矩阵,2.Prim算法。建立邻接矩阵 上述带权无向图对应的二维数组,根据它建立邻接矩阵,如图1建立下列邻接矩阵。注意:INF表示无穷大,表示整数:32767 intA[MAXV][MAXV];Prim算法 普里姆(Prim)算法是一种构造性算法,从候选边中挑
44 10
|
1月前
|
存储 算法 C++
【C++数据结构——图】图的邻接矩阵和邻接表的存储(头歌实践教学平台习题)【合集】
本任务要求编写程序实现图的邻接矩阵和邻接表的存储。需掌握带权有向图、图的邻接矩阵及邻接表的概念。邻接矩阵用于表示顶点间的连接关系,邻接表则通过链表结构存储图信息。测试输入为图的顶点数、边数及邻接矩阵,预期输出为Prim算法求解结果。通关代码提供了完整的C++实现,包括输入、构建和打印邻接矩阵与邻接表的功能。
49 10

热门文章

最新文章

推荐镜像

更多