作者:Vin-莹持_366 | 来源:互联网 | 2024-11-06 09:08
本课程深入探讨了Python中自定义序列类的实现方法,涵盖从基础概念到高级技巧的全面解析。通过实例演示,学员将掌握如何创建支持切片操作的自定义序列对象,并了解`bisect`模块在序列处理中的应用。适合希望提升Python编程技能的中高级开发者。
第三课 python进阶自定义序列类 tags:
categories:
文章目录 第三课 python进阶自定义序列类 第一节 序列类分类 第二节 序列的abc继承关系 第三节 序列的+、+=和extend的区别 第四节 切片基础操作 第五节 自定义可切片的对象 第六节 bisect维护已排序序列 第七节 列表推导式、生成器表达式、字典推导式
第一节 序列类分类 通过序列存储数据的类型区分:容器序列:list、tuple、deque(队列) 扁平序列:str、bytes、bytearray、array.array (数组放置同一种数据类型) 通过序列是否可变进行区分:可变序列:list、deque、bytearray、array 不可变序列:str、tuple、bytes 数组和列表的区别:array和list的一个重要区别, array只能存放指定的数据类型 因为array在使用的时候要指定元素数据类型 ,因此它比list和tuple都有比较高效空间 性能。 from array import array my_array = array( "i" , ( 1 , 5 , 2 , 3 ) ) my_array. append( 1 ) print ( my_array)
第二节 序列的abc继承关系 查看序列的抽象基类,Lib_collections_abc.py。帮助我们理解这些数据结构的协议的细节 。from collections import abc Sequence(不可变)和MutableSequence(可变序列),因为它里面有setitem和delitem魔法函数所以可变。 Sequence发现继承了Reversible和Collection(Sized, Iterable, Container),Sized可以用len(), Iterable可以迭代,Container可以使用if in。这里if in首选__contains__,如果没有的话,退一步 找__getitem__ 第三节 序列的+、+=和extend的区别 +只能拓展同类型的序列 变成元祖就会报错 += 实际上调用了__iadd__魔法函数, 它更加灵活.它内部调用了extend方法 可以加任何可迭代类型。看Lib_collections_abc.py下的__iadd__魔法函数。 extend方法 可以加任何可迭代类型 append把数组当做一个值 添加到尾部 a = [ 1 , 2 ] c = a + [ 3 , 4 ] print ( c) a += [ 3 , 4 ] print ( a) a. extend( range ( 3 ) ) a. append( [ 1 , 2 ] ) print ( a)
第四节 切片基础操作 模式[start: end: step] 切片操作返回新的列表,不会改变原来的元素 第一个数字start表示切片开始位置,默认为0; 第二个数字end表示切片截止(但不包含)位置(默认为列表长度); 第三个数字step表示切片的步长(默认为1)。 当start为0时可以省略,当end为列表长度时可以省略, 当step为1时可以省略,并且省略步长时可以同时省略最后一个冒号。 另外,当step为负整数时,表示反向切片,这时start应该比end的值要大才行。 """其中,第一个数字start表示切片开始位置,默认为0;第二个数字end表示切片截止(但不包含)位置(默认为列表长度);第三个数字step表示切片的步长(默认为1)。当start为0时可以省略,当end为列表长度时可以省略,当step为1时可以省略,并且省略步长时可以同时省略最后一个冒号。另外,当step为负整数时,表示反向切片,这时start应该比end的值要大才行。 """ aList = [ 3 , 4 , 5 , 6 , 7 , 9 , 11 , 13 , 15 , 17 ] print ( aList[ : : ] ) print ( aList[ : : - 1 ] ) print ( aList[ : : 2 ] ) print ( aList[ 1 : : 2 ] ) print ( aList[ 3 : 6 ] ) print ( aList[ 0 : 100 ] ) print ( aList[ 100 : ] ) aList[ len ( aList) : ] = [ 9 ] aList[ : 0 ] = [ 1 , 2 ] aList[ 3 : 3 ] = [ 4 ] aList[ : 3 ] = [ 1 , 2 ] aList[ 3 : ] = [ 4 , 5 , 6 ] aList[ : : 2 ] = [ 0 ] * 3 print ( aList) aList[ : : 2 ] = [ 'a' , 'b' , 'c' ] print ( aList) aList[ : 3 ] = [ ] print ( aList) del aList[ : 3 ] print ( aList) del aList[ : : 2 ] print ( aList)
第五节 自定义可切片的对象 必须实现Sequence里面的下面魔法方法。(这里是不可变切片对象)__reversed__、 __getitem__、 __len__、 __iter__、 __contains__ import numbersclass Group : def __init__ ( self, group_name, company_name, staffs) : self. group_name = group_nameself. company_name = company_nameself. staffs = staffsdef __reversed__ ( self) : self. staffs. reverse( ) def __getitem__ ( self, item) : cls = type ( self) if isinstance ( item, slice ) : return cls( group_name= self. group_name, company_name= self. company_name, staffs= self. staffs[ item] ) elif isinstance ( item, numbers. Integral) : return cls( group_name= self. group_name, company_name= self. company_name, staffs= [ self. staffs[ item] ] ) def __len__ ( self) : return len ( self. staffs) def __iter__ ( self) : return iter ( self. staffs) def __contains__ ( self, item) : if item in self. staffs: return True else : return False staffs = [ "bobby1" , "imooc" , "bobby2" , "bobby3" ] group = Group( company_name= "imooc" , group_name= "user" , staffs= staffs) reversed ( group) for user in group: print ( user)
第六节 bisect维护已排序序列 bisect包中有一个insort插入函数 ,在插入时就维护序列的有序性。使用二分查找算法效率高。 维护已排序的序列,尽量用bisect import bisectfrom collections import deque inter_list = [ ] bisect. insort( inter_list, 3 ) bisect. insort( inter_list, 2 ) bisect. insort( inter_list, 5 ) bisect. insort( inter_list, 1 ) bisect. insort( inter_list, 6 ) bisect. insort_left( inter_list, 1 ) bisect. insort_right( inter_list, 3 ) print ( inter_list) print ( bisect. bisect_left( inter_list, 5 ) ) print ( bisect. bisect_right( inter_list, 5 ) ) print ( inter_list)
第七节 列表推导式、生成器表达式、字典推导式 列表生成式:能用尽量用, 因为效率高 odd_list = [ i for i in range ( 21 ) if i % 2 == 1 ] print ( odd_list) odd_list1 = ( i* i for i in range ( 21 ) if i % 2 == 1 ) print ( odd_list1) print ( type ( odd_list1) ) for i in odd_list1: print ( i) int_list = [ 1 , 2 , - 3 , 4 , 5 ] qu_list = [ item if item > 0 else abs ( item) for item in int_list] print ( qu_list) int_list1 = [ 1 , 2 ] int_list2 = [ 3 , 4 ] qu_list = [ ( first, second) for first in int_list1 for second in int_list2] print ( qu_list) my_dict = { "bobby1" : 22 , "bobby2" : 11 , "bobby3" : 12 } reversed_dict = { value: key for key, value in my_dict. items( ) } print ( reversed_dict) my_set = { key for key, value in my_dict. items( ) } print ( type ( my_set) ) print ( my_set)