• 4.2.1 自定义数组


      任务:自定义一个数组类,支持数组与数字之间的四则运算,数组之间的加法运算、内积运算、和大小比较,数组元素访问和修改,以及成员测试等功能。

      1 class MyArray():
      2     '''All the elements in this array must be numbers'''
      3 
      4     def __IsNumber(self,n):
      5         if not isinstance(n,(int,float,compile)):
      6             return False
      7         return True
      8 
      9     #构造函数,进行必要的初始化
     10     def __init__(self,* args):
     11         if not args:
     12             self.__value = []
     13         else:
     14             for arg in args:
     15                 if not self.__IsNumber(arg):
     16                     print('All elements must be numbers')
     17                     return
     18 
     19         # 将传递进来的参数从tuple类型转换为list类型,这样就能进行后续的操作了。
     20         self.__value = list(args)
     21 
     22     #定义一个析构函数,当该类没有实例的时候,释放内部封装的列表
     23     def __del__(self):
     24         del self.__value
     25 
     26 
     27     #重载运算符 +
     28     #数组中每个元素都与数字n相加,或两个数组相加,返回新数组
     29     def __add__(self,n):
     30         if self.__IsNumber(n):
     31             #数组中所有元素都与数字n相加
     32             b = MyArray()
     33             b.__value = [item + n for item in self.__value]
     34             return b
     35 
     36         elif isinstance(n,MyArray):
     37             #两个等成的数组对应元素相加
     38             if len(n.__value) == len(self.__value):
     39                 c = MyArray()
     40                 c.__value = [i + j for i,j in zip(self.__value,n.__value)]
     41 
     42                 #或者用把列表推导改成for遍历,不过还是推导的执行效率高
     43                 #for i,j in zip(self.__value,n.__value):
     44                 #    c.__value.append(i + j
     45 
     46                 return c
     47 
     48             else:
     49                 print('Length not equal')
     50 
     51         else:
     52             print('Not supported')
     53 
     54 
     55     #重载运算符 -
     56     #数组中每个元素都与数字n相减,返回新数组
     57     def __sub__(self,n):
     58         if not self.__IsNumber(n):
     59             print('- operating with',type(n),'and number type is not supported.')
     60             return
     61 
     62         b = MyArray()
     63         b.__value = [item - n for item in self.__value]
     64         return b
     65 
     66     #重载运算符 *
     67     #数组中每个元素都与数字n相乘,返回新数组
     68     def __mul__(self,n):
     69         if not self.__IsNumber(n):
     70             print('* operating with',type(n),'and number type is not supported.')
     71             return
     72 
     73         b = MyArray()
     74         b.__value = [item * n for item in self.__value]
     75         return b
     76 
     77     #重载运算符 /
     78     #数组中每个元素都与数字 n 相除,返回新数组
     79     def __truediv__(self,n):
     80         if not self.__IsNumber(n):
     81             print(r'/ operating with', type(n), 'and number type is not supported.')
     82             return
     83 
     84         b = MyArray()
     85         b.__value = [item / n for item in self.__value]
     86         return b
     87 
     88 
     89     # 重载运算符 //
     90     # 数组中每个元素都与数字 n 整除,返回新数组
     91     def __floordiv__(self, n):
     92         if not self.__IsNumber(n):
     93             print(r'// operating with', type(n), 'and number type is not supported.')
     94             return
     95 
     96         b = MyArray()
     97         b.__value = [item // n for item in self.__value]
     98         return b
     99 
    100     # 重载运算符 %
    101     # 数组中每个元素都与数字 n 取余,返回新数组
    102     def __mod__(self, n):
    103         if not self.__IsNumber(n):
    104             print('% operating with', type(n), 'and number type is not supported.')
    105             return
    106 
    107         b = MyArray()
    108         b.__value = [item % n for item in self.__value]
    109         return b
    110 
    111         # 重载运算符 **
    112         # 数组中每个元素都与数字 n 进行幂计算,返回新数组
    113     def __pow__(self, n):
    114         if not self.__IsNumber(n):
    115             print('% operating with', type(n), 'and number type is not supported.')
    116             return
    117 
    118         b = MyArray()
    119         b.__value = [item ** n for item in self.__value]
    120         return b
    121 
    122     def __len__(self):
    123         return len(self.__value)
    124 
    125 
    126     #直接使用该类对象作为表达式来查看对象的值
    127     def __repr__(self):
    128         return repr(self.__value)
    129 
    130     #支持使用print()函数查看对象的值
    131     def __str__(self):
    132         return str(self.__value)
    133 
    134 
    135     #往数组中追加元素
    136     def append(self,v):
    137         if not self.__IsNumber(v):
    138             print('Only number can be appended.')
    139             return
    140         self.__value.append(v)
    141 
    142     #获取指定下标的元素值,支持使用列表或元组指定多个下标
    143     def __getitem__(self, index):
    144         length = len(self.__value)
    145         #如果指定单个整数作为下标,则直接返回元素值
    146         if isinstance(index,int) and 0 <= index <= length:
    147             return self.__value[index]
    148 
    149         #使用列表或元组指定多个整数下标
    150         elif isinstance(index,(list,tuple)):
    151             for i in index:
    152                 if not (isinstance(i,int) and 0 <= i < length):
    153                     return 'index error'
    154                 result = []
    155 
    156                 for item in index:
    157                     result.append(self.__value[item])
    158                 return result
    159         else:
    160             return 'index srror'
    161 
    162     #修改元素值,支持使用列表或元组指定多个下标,同时修改多个元素值
    163     def __setitem__(self,index,value):
    164         length = len(self.__value)
    165 
    166         #如果下标合法,则直接修改元素值
    167         if isinstance(index,int) and 0 <= index < length:
    168             self.__value[index] = value
    169 
    170         #支持使用列表或元组指定多个下标
    171         elif isinstance(index,(tuple,list)):
    172             for i in index:
    173                 if not (isinstance(i,int) and 0 <= i < length):
    174                     raise Exception('index error')
    175 
    176             #如果下标和给的值都是列表或元组,并且个数一样
    177             #则分别为多个下标的元素修改值
    178             if isinstance(value,(list,tuple)):
    179                 if len(index) == len(value):
    180                     for i,v in enumerate(index):
    181                         self.__value[v] = value[i]
    182                 else:
    183                     raise Exception('values and index must be of the same length')
    184 
    185             #如果指定多个下标和一个普通值,则把多个元素修改为相同的值
    186             elif isinstance(value,(int,float,complex)):
    187                 for i in index:
    188                     self.__value[i] = value
    189             else:
    190                 raise Exception('value error')
    191 
    192         else:
    193             raise Exception('index error')
    194 
    195     #支持成员测试运算符 in ,测试数组中是否包含某个元素
    196     def __contains__(self,v):
    197         if v in self.__value:
    198             return True
    199         return False
    200 
    201     #模拟向量内积
    202     def dot(self,v):
    203         if not isinstance(v,MyArray):
    204             print(v,'must be an instance of MyArray.')
    205             return
    206         if len(v) != len(self.__value):
    207             print('The size must be equal.')
    208             return
    209         return sum([i * j for i,j in zip(self.__value,v.__value)])
    210 
    211         #或者用如下方式实现
    212         #b = MyArray()
    213         #for m,n in zip(v.__value,self.__value):
    214         #    b.__value.append(m * n)
    215         #return sum(b.__value)
    216 
    217     #重载运算符 == ,测试两个数组是否相等
    218     def __eq__(self,v):
    219         if not isinstance(v,MyArray):
    220             print(v,'must be an instance of MyArray')
    221             return False
    222         if self.__value == v.__value:
    223             return True
    224         return False
    225 
    226     #重载运算符 < ,比较两个数组大小
    227     def __lt__(self,v):
    228         if not isinstance(v,MyArray):
    229             print(v,'must be an instace of MyArray.')
    230             return False
    231         if self.__value < v.__value:
    232             return True
    233         return False
    234 
    235 
    236 if __name__ == '__main__':
    237     print('Please use me as a module.')

      将上面的程序保存为MyArray.py文件,可以作为Python模块导入并使用其中的数组类。

        >>> import os
        >>> os.getcwd()
        'C:UsersddddAppDataLocalProgramsPythonPython35'
        >>>

      把文件放在这个目录下

      1 >>> 
      2 >>> from MyArray import MyArray
      3 >>> 
      4 >>> #导入模块中自定义的类
      5 >>> from MyArray import MyArray
      6 >>> 
      7 >>> #实例化对象
      8 >>> x = MyArray(1,2,3,4,5,6)
      9 >>> y = MyArray(6,5,4,3,2,1)
     10 >>> 
     11 >>> #返回数组长度,即数组中的元素个数
     12 >>> len(x)
     13 6
     14 >>> 
     15 >>> #每个元素加5,返回新数组,原数组值不改变
     16 >>> x + 5
     17 [6, 7, 8, 9, 10, 11]
     18 >>> 
     19 >>> #每个元素值乘以3,返回新数组
     20 >>> x * 3
     21 [3, 6, 9, 12, 15, 18]
     22 >>> 
     23 >>> #计算两个数组(一维向量)的内积
     24 >>> x.dot(y)
     25 56
     26 >>> 
     27 >>> #在数组尾部追加新元素
     28 >>> x.append(7)
     29 >>> x
     30 [1, 2, 3, 4, 5, 6, 7]
     31 >>> 
     32 >>> #x数组追加新元素后,两个数组元素数不相等,看看进行内积的计算会如何
     33 >>> x.dot(y)
     34 The size must be equal.
     35 >>> 
     36 >>> #试图修改元素值
     37 >>> x[9] = 8
     38 Traceback (most recent call last):
     39   File "<pyshell#30>", line 1, in <module>
     40     x[9] = 8
     41   File "C:UsersddddAppDataLocalProgramsPythonPython35MyArray.py", line 193, in __setitem__
     42     raise Exception('index error')
     43 Exception: index error
     44 >>> #根据报错内容可知,是下标越界了,因为x数组中只有7个元素
     45 >>> 
     46 >>> #x数组中的每个元素值除以 2
     47 >>> x / 2
     48 [0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5]
     49 >>> 
     50 >>> x // 2
     51 [0, 1, 1, 2, 2, 3, 3]
     52 >>> 
     53 >>> x % 3
     54 [1, 2, 0, 1, 2, 0, 1]
     55 >>> 
     56 >>> #返回固定位置的元素值
     57 >>> x[2]
     58 3
     59 >>> 
     60 >>> #测试数组中是否包含某个元素
     61 >>> 'a' in x
     62 False
     63 >>> 
     64 >>> 3 in x
     65 True
     66 >>> 
     67 >>> #比较数组的大小
     68 >>> x < y
     69 True
     70 >>> 
     71 >>> x = MyArray(1,2,3,4,5,6)
     72 >>> 
     73 >>> #两个数组中对应元素相加,返回新数组
     74 >>> x + y
     75 Traceback (most recent call last):
     76   File "<pyshell#54>", line 1, in <module>
     77     x + y
     78   File "C:UsersddddAppDataLocalProgramsPythonPython35MyArray.py", line 30, in __add__
     79     if self.__IsNumber(n):
     80   File "C:UsersddddAppDataLocalProgramsPythonPython35MyArray.py", line 5, in __IsNumber
     81     if not isinstance(n,(int,float,compile)):
     82 TypeError: isinstance() arg 2 must be a type or tuple of types
     83 >>> 
     84 >>> 
     85 >>> #查看多个位置上的元素值
     86 >>> x[[1,3,4]]
     87 [2, 4, 5]
     88 >>> 
     89 >>> 
     90 >>> #同时修改多个元素的值
     91 >>> x[[2.3]] = [8,9]
     92 Traceback (most recent call last):
     93   File "<pyshell#62>", line 1, in <module>
     94     x[[2.3]] = [8,9]
     95   File "C:UsersddddAppDataLocalProgramsPythonPython35MyArray.py", line 174, in __setitem__
     96     raise Exception('index error')
     97 Exception: index error
     98 >>> 
     99 >>> #为多个元素赋值为相同的值
    100 >>> x[[1,3,5]] = 0
    101 >>> x
    102 [1, 0, 3, 0, 5, 0]
    103 >>> 
  • 相关阅读:
    海龟交易
    暑假攻略:怎样让孩子过一个充实又省钱的假期
    值得追随
    在哪里能找的你想要的答案?
    顺势加仓策略
    交易中 你的加仓策略是怎样的?背后的逻辑是什么?
    驻守深寒:寻找那些有效地关键K线
    统计相关
    求助Ubuntu16.10如何设置默认启动为字符界面
    【Linux系列】Ubuntu ping通,xshell无法连接
  • 原文地址:https://www.cnblogs.com/avention/p/8652631.html
Copyright © 2020-2023  润新知