5.1 序列类型的分类
容器序列
list、tuple、deque
扁平序列[同一种数据类型]
str、bytes、bytearray、array.array
可变序列
list, deque,bytearray、array
不可变
str、tuple、bytes
5.2 序列的abc继承关系
from collections import abc
5.3 序列的+、+=和extend的区别
a = [1,2] c = a + [3,4] # c = a + (3,4) #抛异常,+ 号两边必须为相同的类型 print(c) #就地加 a += (3,4) #可以为任意序列类型 # __iadd__ 实现 print(a) a.extend(range(3)) a.append((1,2)) print(a) --- [1, 2, 3, 4] [1, 2, 3, 4] [1, 2, 3, 4, 0, 1, 2, (1, 2)]
5.4 实现可切片的对象
# 模式[start:end:step] """ 其中,第一个数字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]) # 指定切片的开始和结束位置 aList[0:100] # 切片结束位置大于列表长度时,从列表尾部截断 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'] # 隔一个修改一个 aList[::2] = [1, 2] # 左侧切片不连续,等号两边列表长度必须相等 aList[:3] = [] # 删除列表中前3个元素 del aList[:3] # 切片元素连续 del aList[::2] # 切片元素不连续,隔一个删一个
手动实现序列类型
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: # if xx in 会调用该魔法函数 return True else: return False staffs = ["lewen1", "imooc", "lewen2", "lewen3"] group = Group(company_name="imooc", group_name="user", staffs=staffs) reversed(group) for user in group: print(user)
---
lewen3
lewen2
imooc
lewen1
5.5 bisect管理可排序序列
import bisect from collections import deque #用来处理已排序的序列,用来维持已排序的序列, 升序 #二分查找 # inter_list = [] inter_list = deque() 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) --- deque([1, 2, 3, 5, 6]) print(bisect.bisect_left(inter_list, 7)) # 插入的数据在列表中的位置 print(bisect.bisect_right(inter_list, 7)) --- 5 5
5.6 什么时候我们不该用列表
# array, deque # 数组 [连续的内存空间] import array # array和list的一个重要区别, array只能存放指定的数据类型 my_array = array.array("i") my_array.append(1) my_array.append("abc") --- TypeError: an integer is required (got type str)
5.7 列表推导式、生成器表达式、字典推导式
# 列表生成式 # 提取出1-20 之间的奇数 odd_list = [i for i in range(21) if i %2 ==1 ] print(odd_list) [1, 3, 5, 7, 9, 11, 13, 15, 17, 19] def hand_item(item): return item*item odd_list = [hand_item(i) for i in range(21) if i%2==1] print(odd_list) [1, 9, 25, 49, 81, 121, 169, 225, 289, 361]
# 生成器表达式 odd_gen = (i for i in range(21) if i %2 ==1) print(odd_gen) # for item in odd_gen: # print(item) odd_list = list(odd_gen) print(type(odd_list)) <generator object <genexpr> at 0x000001DF69EAC7C8> <class 'list'>
# 字典推导式 my_dict = {"lewen":22,"city":"cq","code":408200} reversed_dict = {value:key for key,value in my_dict.items()} print(reversed_dict) {22: 'lewen', 'cq': 'city', 408200: 'code'}
# 集合推导式 my_set = {key for key ,value in my_dict.items()} # my_set = set(my_dict.keys()) # 取巧的方法 print(type(my_set)) print(my_set) <class 'set'> {'city', 'code', 'lewen'}