自定义序列类:理解序列
《Python3高级核心技术97讲,bobby》学习笔记,第四章:理解序列类。
344阅读 · 2020-6-8 23:44发布
4.1 序列类型的分类
- 容器序列(可以接收不同类型数据):list、tuple、deque
- 扁平序列:str、bytes、bytearray、array.array
- 可变序列:list、deque、bytearray、array
- 不可变:str、tuple、bytes
4.2 序列类型的abc继承关系
- 通过collection的abc可以查看所有数据结构的抽象基类(可以学习序列需要实现哪些魔法函数)。
- 序列相关抽象基类:Sequence(不可变序列)、MutableSequence(可变序列)。
- Sequence抽象基类:
class Sequence(_Collection[_T_co], Reversible[_T_co], Generic[_T_co]): @overload @abstractmethod def __getitem__(self, i: int) -> _T_co: ... @overload @abstractmethod def __getitem__(self, s: slice) -> Sequence[_T_co]: ... # Mixin methods if sys.version_info >= (3, 5): def index(self, x: Any, start: int = ..., end: int = ...) -> int: ... else: def index(self, x: Any) -> int: ... def count(self, x: Any) -> int: ... def __contains__(self, x: object) -> bool: ... def __iter__(self) -> Iterator[_T_co]: ... def __reversed__(self) -> Iterator[_T_co]: ...
- MutableSequence抽象基类:
class MutableSequence(Sequence[_T], Generic[_T]): @abstractmethod def insert(self, index: int, object: _T) -> None: ... @overload @abstractmethod def __setitem__(self, i: int, o: _T) -> None: ... @overload @abstractmethod def __setitem__(self, s: slice, o: Iterable[_T]) -> None: ... @overload @abstractmethod def __delitem__(self, i: int) -> None: ... @overload @abstractmethod def __delitem__(self, i: slice) -> None: ... # Mixin methods def append(self, object: _T) -> None: ... def clear(self) -> None: ... def extend(self, iterable: Iterable[_T]) -> None: ... def reverse(self) -> None: ... def pop(self, index: int = ...) -> _T: ... def remove(self, object: _T) -> None: ... def __iadd__(self, x: Iterable[_T]) -> MutableSequence[_T]: ...
4.3 list的extend方法
- “+=”运算实际是执行iadd魔法函数中的代码实现。
- iadd中会使用extend方法,extend方法会遍历可迭代的参数进行相加。
- extend没有返回值,在原实例上做修改。
4.4 实现可切片的对象
- 实现getitem即可实现可切片操作。
- getitem接收一个item参数,参数是int类型或者slice(切片对象)。
实现切片代码示例:
import numbers class Group: def __init__(self,name,value): self.name = name self.staffs = staffs def __getitem__(self,item): clas = type(self) if isinstance(item,slice): return cls(name=self.name,staffs=self.staffs) elif isinstance(item, numbers.Integral): return cls(name=self.name,staffs=[self.staffs])
4.5 通过bisect维护已排序序列
- 使用bisect包,用来处理已排序的序列。
- bisect使用二分查找
代码示例:
# from collections import deque # inter_deque = 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.bisect(inter_list,3) # 默认使用的是bisect_right,重复数据的右侧插入 bisect.bisect_left(inter_list,3) # 在重复数据的左侧插入
4.6 除了list之外的序列
- 序列都有不同的特性,根据需要选择适合的序列才是正确的做法。例如下面的array在单一数据存储的场景下,会比list性能高。(建议自行多了解其他序列)
- array只能存放指定的类型,它的性能比list高很多。
- array代码示例:
import array my_array = array.array("i") my_array.append(1)
4.7 列表推导式、生成器表达式、字典推导式用法介绍
列表推导式
1. 简单:提取1-20之间的奇数 odd_list = [i for i in range(21) if i % 2 == 1] 2. 复杂:逻辑较复杂的情况 def handle_item(item): return item * item odd_list = [ handle_item(i) for item 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)
字典推导式
my_dict = {"aaa":111, "bbb":222,"ccc":333} reversed_dict = {value:key for key,value in my_dict.items()}