1. 序列类型的分类:
容器类型:list、tuple,deque
扁平序列:str、bytes、bytearray、array.array
可变序列:list、dequte、bytearray、array
不可变序列:str、tuple、bytes
2. 序列的abc继承关系:
魔法函数构成了协议
3.序列的+ +=和extend的区别:
my_list = [] my_list.append(1) my_list.append("a") from collections import abc a = [1,2] # a = list() c = a + [3,4] # c = a + (3,4) # 抛异常 print(c) # 就地加 a += [3,4] a += (3,4) # 可以为任意的序列类型 a.extend((3,4)) # def __iadd__(self, values): # self.extend(values) # return self a.append((1,2,4)) print(a)
记住:我们知道类函数的实现是通过魔法函数来实现的。其中+号表示的是同类项的相加。
记住:+=和extend是一样的,因此+=是通过__iadd__来实现extend的。
记住:append表示添加的是元素位置。
记住:不能用变量名去接收这些方法,因为没有返回值(aa = a.extend是错误的)
4. 实现可切片的对象:
# 模式[start:end:step] r""" 其中,第一个数字start表示切片开始位置,默认是0 第二个数字end表示切片截止(但不包含)位置(默认为列表长度】 第三个数字step表示切片的步长(默认为1) 当start为0时可以省略,当end为列表长度时可以省略。 当start为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] print(aList) # 在列表尾部增加元素 aList[:0] = [1,2] print(aList) # 在列表头部插入元素 aList[3:3] = [4] print(aList) # 在列表中间位置插入元素 aList[:3] = [1,2] print(aList) #替换元素列表元素,等号两边的里诶包长度相同 aList[3:] = [4,5,6] print(aList) # 等号两边的列表长度也可以不相等 aList[::2] = [0] * 3 # 将元素赋值三份 print(aList) # 隔一个修改一个 aList[::2] = ['a','b','c'] # 隔一个修改一个 print(aList) # aList[::2] = [1,2] # 左侧切片不连续,等号两边列表长度必须相等 aList[:3] = [] #删除列表中前3个元素 del aList[:3] # 切片元素连续 del aList[::3] # 切片元素不连续,隔一个删一个。 print(aList)
import numbers class Group: # 支持切片操作 def __init__(self,group_name,company_name,staffs): self.group_name = group_name self.company_name = company_name self.staffs = staffs def __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) sub_group = group[:2] print(group.staffs) # sub_group1 = group[0] # print(group.staffs) # reversed(group) # for user in group: # print(user)
记住:这是一个比较多的用魔法函数实现切片操作。
记住:难理解的是cls = type(self),返回值:<class '__main__.Group'>,这是拿到类的对象 ,其实可以改写成下面方式
def __getitem__(self, item): # cls = type(self) # print(type(self)) if isinstance(item,slice): return Group(group_name=self.group_name,company_name=self.company_name,staffs=self.staffs[item]) elif isinstance(item,numbers.Integral): return Group(group_name=self.group_name,company_name=self.company_name,staffs=[self.staffs[item]])
记住:但是这里为什么要用type返回类对象呢?这是一种相对方式,为的是如果更改类名可以不用修改内部的代码。
5. bisect二分迭代类型操作:
import bisect from 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) print(inter_list) # 总结: # bisect.bisect(data,1) # 作用,查找该数值将会插入的位置并返回,而不会插入,返回是会在那个数字之后插入 # 表示:num > .... 插入 a1 = bisect.bisect(inter_list,4) print(a1) # bisect_left 和 bisect_right 函数 # 该函数用入处理将会插入重复数值的情况,返回将会插入的位置 # 第一:从左边看num>...插入位置 # 第二:从右边看 ... < num 出入位置。 a2 = bisect.bisect_left(inter_list,2) print(a2) a3 = bisect.bisect_right(inter_list,2) print(a3) # insort 函数 insort_left 和 insort_right bisect.insort(inter_list,2) print(inter_list)
7.数组:
# array, deque # 数组:存储连续的内存空间,效率非常高的。 import array # array 和list的一个重要区别,array只能存放指定的数据类型。 # array的性能比list高。 my_array = array.array("i") my_array.append(1) my_array.append("abc") print(my_array)
记住:我们是会用 列表,什么时候用数组
8. 列表推导式、生成器表达式、字典推导式、集合推导式。
# 列表生成式(列表推导式) # 1. 提取1-20之间的奇数 odd_list = [] for i in range(21): if i %2 ==1: odd_list.append(i) print(odd_list) # 列表生成式 odd_list = [i for i in range(21) if i %2 == 1 ] # 2.逻辑复杂的情况 def handle_item(item): return item * item odd_list1 = [handle_item(i) for i in range(21) if i %2 == 1 ] # 列表生成式性能高于列表操作。
记住:列表生成式不能太复杂了。要不就放弃了可读性。另外列表生成式的操作高于列表操作。
# 生成器表达式: odd_list = (i for i in range(21) if i %2 == 1 ) print(type(odd_list)) # <class 'generator'> for item in odd_list: print(item)
记住:生成器通过for循环打印出来。
odd_gen = (i for i in range(21) if i %2 == 1 ) odd_list = list(odd_gen) print(odd_list)
记住:生成器可以转回成list再打印出来也是可以的。
# 字典推导式 my_dict = {"bobby1":22,"bobby2":23,"imooc":5} reversed_dict = {value:Key for Key,value in my_dict.items()} print(reversed_dict) # {22: 'bobby1', 23: 'bobby2', 5: 'imooc'}
# 集合推导式 # my_set = set(my_dict.keys()) my_set = {Key for Key,value in my_dict.items()} print(my_set) print(type(my_set)) # <class 'set'>