Python集合模块 Collections
概述
在collections中,主要包括如下相关类和方法:
相关类/方法 | 描述 |
---|---|
namedtuple() | 创建命名元组子类的工厂函数,生成可以使用名字来访问元素内容的tuple子类 |
deque | 类似列表(list)的容器,实现了在两端快速添加(append)和弹出(pop) |
ChainMap | 类似字典(dict)的容器类,将多个映射集合到一个视图里面 |
Counter | 字典的子类,提供了可哈希对象的计数功能 |
OrderedDict | 字典的子类,保存了他们被添加的顺序,有序字典 |
defaultdict | 字典的子类,提供了一个工厂函数,为字典查询提供一个默认值 |
UserDict | 封装了字典对象,简化了字典子类化 |
UserList | 封装了列表对象,简化了列表子类化 |
UserString | 封装了字符串对象,简化了字符串子类化 |
我们可以引入该模块,然后打印出对应的信息:
1 |
|
Named Tuple
named tuple含义为命名元组,它可以帮助我们生成一个允许使用名字访问元素内容的Tuple子类,提高程序的可读性。
例如,如果我们需要表示平面上的一个点,我们可以使用一个元组(x, y)
来进行表示,但是这样的元组只能用下标来访问其中的内容。另一种解决方案是定义一个类Point,其中保存对应的坐标。而命名元组实际上就可以帮助我们更加简单地构造出这样一个类,利用该方法,我们可以指定类名以及元组的名次,之后就可以用更加具有可读性的代码来完成相关工作。
1 |
|
namedtuple
可以接收如下参数:
typename
:指定所创建的tuple子类的类名field_names
:接收一个字符串序列,用于表示tuple中的字段名称rename
:如果该参数设置为True,那么无效的字段会被自动替换为位置名称verbose
:如果该参数设置为True,那么子类被创建之后,类定义就会被立即打印出来module
:用于指定类所在的module
Deque
python原生的list类型是线性存储数据的,按照索引访问元素很快,但是数据量很大的时候,插入和删除效率较低,而deque
是一个双端队列,其中高效实现了插入和删除操作,适合用于队列和栈。
1 |
|
deque和list具有几乎相同的使用方式,相关方法如下:
append(x)
:向队尾添加元素appendleft(x)
:向队首添加元素clear()
:清空队列元素copy()
:获得一个浅拷贝count(x)
:计算队列中值为x的个数extend(x_deque)
:向队尾扩展队列extendleft(x_deque)
:向队首扩展队列index(x)
:获取x的下标indexinsert(index, x)
:在指定index处插入值xpop()
:弹出队尾元素popleft()
:弹出队首元素remove(value)
:删除第一个value值reverse()
:队列反转rotate(n=1)
:将队列向右循环移动n步maxlen
:deque的最大尺寸
Chain Map
ChainMap
可以把一组dict
组合成一个逻辑上的dict。在使用的使用,仍然可以按照操作一个dict那样操作,但是内部的逻辑则会在这组dict上依次进行。实际上,ChainMap实际上就是一个映射链,在进行操作的时候,会依次在内部的链上进行。
ChainMap的一个常见应用场景是程序参数的获取。在获取应用程序参数的时候,我们通常可以从三个地方获取,分别是命令行传入、环境变量传入以及默认参数,它们可以对应三个dict,利用ChainMap可以实现参数的优先级查找。
1 |
|
之后我们可以使用不同方式传入相关参数:
1 |
|
Counter
Counter
是一个计数器,可以帮助我们统计次数。它本身也是dict
的一个子类,key为元素值,value则为对应元素值出现的次数。
1 |
|
Counter作为dict的子类,能够提供dict相关的方法,同时它本身还提供了一些特有的方法:
elements()
:返回一个迭代器,其中每个元素将重复计数器所指定的次数,同时元素会按照首次出现的顺序返回most_common(n)
:返回一个列表,其中包含n个出现最多的元素以及对应的出现次数。计数值相等的元素按照首次出现的顺序进行排序。如果n为None,则返回所有元素substract(another_counter)
:从迭代对象或者映射对象减去元素,对应值对应相减
此外,Counter还提供强大的数学操作功能,要点在于对应位置的值进行对应操作,如果得到的计数小于等于0则会被忽略
1 |
|
Ordered Dict
在使用dict的时候,key是无序的,因此我们在对dict进行迭代的时候,是无法确定key的顺序的,而OrderedDict
就为我们解决了这个问题。它可以按照插入的顺序对Key进行保存,这样在进行迭代的时候同样是可以保证顺序的。
1 |
|
OrderedDict的使用方法几乎等同于内置的dict,不过它自身还是提供了一些其他的功能:
popitem(last=True)
:移除字典中的一个键值对。如果last为真,则按照LIFO后进先出的顺序返回键值对,否则按照FIFO先进先出的顺序返回键值对move_to_end(key, last=True)
:将key对应的键值对移动到其中一端。如果last为True则移动到最后,否则移动到开头reversed(order_list)
:相对于通常的映射方法,有序字典还另外提供了逆序迭代的支持
需要注意,Python3.8之后,内置的dict已经是有序的了。
Default Dict
使用Python内置的dict,如果我们访问一个不存在的key,则会抛出KeyError错误。而defaultdict
可以帮助我们指定默认值,如果Key不存在,返回的是实现指定的默认值。而default dict
的其他使用方式与内置的dict完全相同。
defaultdict
对象包含一个名为default_factory
的属性。在构造的时候,第一个参数用于为该属性提供初始构造方法,默认为
None。所有其他参数(包括关键字参数)都相当于传递给 dict 的构造函数。
1 |
|
例如这里我们使用list作为default_factory。当第一次遇见某个key的时候,它还没有在字典里面,所以会自动创建,调用default_factory方法返回一个空的list,之后空的list进行append。再次遇到对应的key,就与正常dict操作相同了。
基类
除了上面专门的数据类型之外,在Collections中还提供了三个基类,分别是UserDict、UserList和UserString,以方便用户创建自定义的字典、列表和字符串。如果我们想要自定义类似于dict、list和str的类,那么可以继承这些基类,之后进行个性化地定制即可。