当前位置: 首页 > 后端技术 > Python

Python标准库的集合(数据类型)

时间:2023-03-25 23:44:10 Python

虽然Python提供了一些简单的数据结构类型,如list、tuple、set、dict;这些数据类型可以满足我们的日常使用,而集合就是代替这些标准数据类型而来的。快速查看表集合提供8个对象和1个工厂函数对象function类似于列表(list)的双端队列容器,实现两端快速添加(append)和弹出(pop)ChainMap容器??类类似于字典(dict),一个集合多个映射到一个视图Counter字典的子类,提供可哈希对象的计数功能OrderedDict字典的子类,保存它们添加的顺序UserDict封装字典对象,简化字典子类化UserList封装列表对象,简化列表subclassingUserString封装list对象,简化stringsubclassingnamedtuple()创建namedtuple的工厂函数子类defaultdictdictionary的子类为dictionary提供工厂函数查询提供默认的namedtuple()语法:namedtuple(typename,field_names,*,rename=False,defaults=None,module=None)namedtuple()是一个工厂返回类元组对象的函数typename(tuple的子类,因为它继承自tuple)部分源码result=type(typename,(tuple,),class_namespace)field_names是一个列表,表示字段名(此类对象的参数名称);rename表示将无效的参数名自动转换为位置参数,转换格式为“_”+位置索引;源代码的一部分ifrename:seen=set()forindex,nameinenumerate(field_names):if(notname.isidentifier()or_iskeyword(name)orname.startswith('_')ornameinseen):field_names[index]=f'_{index}'seen.add(name)defaults是为field_names提供默认值,其类型为可迭代对象。(注意:defaults匹配最右边的参数,比如参数['x','y','z']和默认值(1,2),y默认值1,z默认值2)module如果有值,它将覆盖类对象的__module__属性。使用这个元组类对象创建对象,可以通过字段名获取属性值,也可以通过索引和迭代获取值。官方示例代码:>>>Point=namedtuple('Point',['x','y'])>>>Point.__doc__#类对象'Point(x,y)'的文档字符串>>>p=Point(11,y=22)#用位置参数或关键字实例化>>>p[0]+p[1]#像普通元组一样可索引33>>>x,y=p#像普通元组一样解包>>>>x,y(11,22)>>>p.x+p.y#按名称访问字段33>>>d=p._asdict()#转换为字典>>>d['x']11>>>Point(**d)#从字典转换Point(x=11,y=22)>>>p._replace(x=100)#_replace()类似于str.replace(),但以命名参数为目标point(x=100,y=22)defaultdictdefaultdict返回一个包含默认值的字典对象defaultdict接收一个参数default_factory,它是defaultdict对象的一个??属性;构造时,第一个参数为这个属性提供一个初始值,默认为None。默认情况下,dict没有默认值。当我们得到一个不存在的key时,会触发KeyError。通过setdefault和get方法,我们可以为获取一个不存在的key设置默认值,但是defaultdict可以更简单高效的处理默认值。问题。创建具有默认值的字典:In[1]:fromcollectionsimportdefaultdictIn[2]:d=defaultdict(int,{'a':1,'b':2})In[3]:d['a']Out[3]:1In[4]:d['b']Out[4]:2In[5]:d['c']Out[5]:0统计题:s=[('yellow',1),('blue',2),('yellow',3),('blue',4),('red',1)]d=defaultdict(list)fork,vins:d[k].append(v)r=sorted(d.items())print(r)#[('蓝色',[2,4]),('红色',[1]),('黄色',[1,3])]deque(双端队列)语法:deque([iterable[,maxlen]])deque是双端队列,是一种兼具队列和栈属性的数据结构.iterable参数是一个可迭代对象,maxlen用于限制队列的最大长度。如果没有deque,我们一般使用list作为队列和栈,使用pop弹出元素,使用append添加元素。官方文档是这样说的:虽然list对象也支持类似的操作,但是这里优化了定长操作和pop(0)和insert(0,v)的开销。它们导致O(n)内存移动操作,改变底层数据表示的大小和位置。deque支持list的所有操作,并添加了:appendleft(x)将x附加到左侧。extendleft(iterable)通过在可迭代参数中添加元素来扩展双端队列的左侧。注意,添加left时,iterable参数中的顺序会在结果中逆序添加。popleft()删除并返回一个元素,即双端队列中最左边的一个。如果没有元素,则引发IndexError。rotate(n=1)向右旋转n步。如果n为负数,则向左循环。如果双端队列不为空,向右一步相当于d.appendleft(d.pop()),向左一步相当于d.append(d.popleft())。In[1]:fromcollectionsimportdequeIn[2]:d=deque('abcd')In[3]:dOut[3]:deque(['a','b','c','d'])In[4]:d.popleft()Out[4]:'a'In[5]:d.pop()Out[5]:'d'In[6]:d.extendleft('efg')In[7]:dOut[7]:deque(['g','f','e','b','c'])In[8]:d.rotate()In[9]:dOut[9]:deque(['c','g','f','e','b'])In[10]:d.rotate(-1)In[11]:dOut[11]:双端队列(['g','f','e','b','c'])?官方示例用法ChainMap官方文档解释:一个ChainMap类是将多个映射快速链接在一起,以便将它们视为一个单元。它通常比创建新字典并多次调用update()快得多。此类可用于模拟嵌套范围,并且在模板化时很有用。ChainMap结合了多个字典(或其他映射)。创建一个单一的、可更新的视图。In[1]:fromcollectionsimportChainMapIn[2]:cm=ChainMap({'a':'A','b':'B'},{'c':'C','b':'BB'})In[3]:cmOut[3]:ChainMap({'a':'A','b':'B'},{'c':'C','b':'BB'})In[4]:list(cm)Out[4]:['c','b','a']In[5]:cm['b']Out[5]:'B'In[6]:cm['b']='BBB'In[7]:cmOut[7]:ChainMap({'a':'A','b':'BBB'},{'c':'C','b':'BB'})In[8]:cm.mapsOut[8]:[{'a':'A','b':'BB'},{'c':'C','b':'BB'}]基本映射存储在列表中。可以使用maps属性访问或更新该列表。Find不断搜索底层映射,直到找到一个键。相反,写入、更新和删除只对第一个映射进行操作。部分源代码def__getitem__(self,key):formappinginself.maps:try:returnmapping[key]#can'tuse'keyinmapping'withdefaultdictexceptKeyError:passreturnself.__missing__(key)#支持定义__missing__def__setitem__(self,key,value)的子类:self.maps[0][key]=valuedef__delitem__(self,key):try:delself.maps[0][key]exceptKeyError:raiseKeyError('Keynotfoundinthefirstmapping:{!r}'.format(key))defpop(self,key,*args):try:returnself.maps[0].pop(key,*args)除了KeyError:raiseKeyError('Keynotfoundinthefirstmapping:{!r}'.format(key))ChainMap支持dict的所有方法;此外,ChainMap还包含一个可以更新的映射列表maps,如上所述。还有new_child,它返回一个新的ChainMap,它有一个参数m。如果m有内容,返回的ChainMap会在映射列表前加上m;否则,添加一个空字典。In[1]:fromcollectionsimportChainMapIn[2]:cm=ChainMap({'a':'A','b':'B'},{'c':'C','b':'BB'})In[3]:n_cm=cm.new_child()In[4]:n_cmOut[4]:ChainMap({},{'a':'A','b':'B'},{'c':'C','b':'BB'})在[5]中:n_cm=cm。new_child({'e':'E','f':'F'})In[6]:n_cmOut[6]:ChainMap({'e':'E','f':'F'},{'a':'A','b':'B'},{'c':'C','b':'BB'})部分源码defnew_child(self,m=None):如果m是None:m={}returnself.__class__(m,*self.maps)和parents,它返回映射列表中除第一个以外的所有字典的A映射。In[1]:fromcollectionsimportChainMapIn[2]:cm=ChainMap({'a':'A','b':'B'},{'c':'C','b':'BB'})In[3]:cm.parentsOut[3]:ChainMap({'c':'C','b':'BB'})与ChainMap(*cm.maps[1:]).部分源码@propertydefparents(self):returnself.__class__(*self.maps[1:])CounterCounter是一个计数器,它接收的参数是一个可迭代对象或者一个map对象,当然也可以是一个Counter对象,只要它能Hash对象那么就可以计数。Counter是dict的子类。In[1]:fromcollectionsimportCounterIn[2]:Counter('abcdaccd')Out[2]:Counter({'a':2,'b':1,'c':3,'d':2})In[3]:Counter(['hey','hello','hey'])Out[3]:Counter({'hey':2,'hello':1})Counter支持字典的所有方法并且还提供了3个方法:elements()返回一个迭代器,每个元素重复多少次就多少次。元素按第一次出现的顺序返回。如果元素的计数小于一,则忽略该元素。In[1]:fromcollectionsimportCounterIn[2]:c=Counter('abcdaccd')In[3]:c.elements()Out[3]:In[4]:sorted(c.elements())Out[4]:['a','a','b','c','c','c','d','d']most_common([n])返回n个最常见元素及其计数的列表,从最常见到最不常见。如果n为None,则列出所有元素的计数。计数值相等的元素按第一次出现的顺序排序。In[1]:fromcollectionsimportCounterIn[2]:c=Counter('abcdaccd')In[3]:c.most_common()Out[3]:[('c',3),('a',2),('d',2),('b',1)]In[4]:c.most_common(2)Out[4]:[('c',3),('a',2)]subtract([iterable-or-mapping])从可迭代或映射对象中减去元素。与dict.update()相同,但减去计数而不是替换它们。计数可以减少到零以下。输入和输出都允许0和负数。In[1]:fromcollectionsimportCounterIn[2]:c=Counter('abcdaccd')In[3]:cOut[3]:Counter({'a':2,'b':1,'c':3、'd':2})In[4]:c.subtract('cd')In[5]:cOut[5]:Counter({'a':2,'b':1,'c':2,'d':1})值得注意的是fromkeys并没有实现,原因在源码中有注释:对于计数器,没有等效的方法,因为在Counter.fromkeys('aaabbc',v=2)在这种情况下,语义会很模糊。不必将计数器初始化为零值,因为零已经是计数器查找的默认值。可以使用Counter(set(iterable))轻松将其初始化为1。对于更奇特的情况,首先创建一个带有字典理解或dict.fromkeys()的字典。update与字典的工作方式也略有不同,例如dict.update(),但会添加计数而不是替换它们。update参数可以是可迭代对象、字典或另一个Counter实例。关于Counter的显示操作:位操作组合(|)是取任意一个Counter计数器的最大值。按位交集(&)是Counter计数对应的最小值。减去一个计数器,但只保留正结果。添加计数器,但只保留正面结果。...In[1]:fromcollectionsimportCounterIn[2]:c=Counter('abcdaccd')In[3]:cc=Counter('abdd')In[4]:cc&cOut[4]:计??数器({'a':1,'b':1,'d':2})In[5]:cc|cOut[5]:Counter({'a':2,'b':1,'d':2,'c':3})In[6]:c-ccOut[6]:Counter({'a':1,'c':3})In[7]:c+ccOut[7]:Counter({'a':3,'b':2,'c':3,'d':4})OrderedDict顾名思义,有一个有序字典。它是dict的子类,OrderedDict记录了字典插入时的顺序。popitem(last=True)从字典中移除并返回一个(key,value)键值对。如果last为True,则按LIFO顺序返回键值对,如果为False,则按FIFO顺序返回键值对。move_to_end(key,last=True)将现有元素键移动到末尾(如果last为False,则移动到开头)。如果元素不存在,则引发KeyError。OrderedDict也可以通过reversed()进行逆序迭代,每次迭代对象得到OrderedDict对象的key。In[1]:fromcollectionsimportOrderedDictIn[2]:od=OrderedDict({'a':'A','b':'B','c':'C'})In[3]:odOut[3]:OrderedDict([('a','A'),('b','B'),('c','C')])In[4]:od.popitem()Out[4]:('c','C')In[5]:od.move_to_end('a')In[6]:odOut[6]:OrderedDict([('b','B'),('a','A')])In[7]:r_od=reversed(od)In[8]:r_odOut[8]:In[9]:list(r_od)Out[9]:['a','b']extrathings一般使用上面的数据类型就够了,但是总有一些特殊的类型需要定制。Collections提供了一个更容易处理的类,方便你基于它构造自己的类型,而不是直接使用继承的底层数据结构。UserDictUserDict类用作字典对象的包装器。UserList类封装了列表对象。UserStringUserString类用作字符串对象的包装器。

最新推荐
猜你喜欢