1
序列类型
最常用的数据类型
按照结构维度划分:
序列分为容器序列和扁平序列。
容器序列 list、tuple、deque 扁平序列
str、bytes、bytearray、array
注
意
以下提到的抽象基类是python提供的模块
collections.abc中所实现的数据结构,导
入模块即可查看类抽象源码。
常用的序列类型list
list中extend方法和 的区别
=和 的区别
=又叫就地加,是通过一个模板函数来实现的(可以参考抽象基类中的可变序列类型MutableSequence)
号只能加相同的数据类型,而且数据类型有要求,可以相加整型浮点型和序列类型。
extend和append的区别:
extend是增加可迭代对象,类似于 =
append是增加一个对象
什么时候不使用list
list是我们常用的数据类型,但是有的时候并不是所有场景都用它最好。和它想相似的数据类型有两个,一个是array(c语言的数组),还有一个deque。
array和list的区别:
array只能存放指定的数据类型,有点类似go。在这里不做阐述。
list和deque的区别:
它们功能上是类似的,list.pop(0)和deque.popleft()都可以实现左侧的删除,但是在时间上有非常大的差别。
list是动态的,deque是静态的,deque栈底永远不会变,deque的popleft只是把下一个元素变成栈底,pop的元素还在那里,但是list是栈底弹出,其他全部前移。
在BFS的实现中,需要大量的popleft,所以用deque可以节约大量的时间。
2
实现自定义序列类
自己实现一个可以切片的类
在之前的文章中,我们提到了python的协议是由魔法函数的机制去实现的。那么在这里如果我想要自定义一个序列类,我不需要继承序列类的属性,而只通过在类中实现序列相同的方法就可以获得与序列类一致的数据特性的类。
自定义序列的实现
如何知道数据类型有哪些抽象方法
先回答这个问题,在之前得注意中有写到。python中提供了一个数据结构的抽象类模块。叫做collections.abc
通过这个模块的Sequence(序列)可以查看到序列结构需要实现哪些抽象方法。如下图:
代码如下:
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)
reversed(group)
for user in group:
print(user)