自定义序列类:理解序列

《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()}