Python的collections模块真的很好用
collections是实现了特定目标的容器,以提供Python标准内建容器 dict , list , set , 和 tuple 的替代选择。为了让大家更好的认识,本文详细总结collections的相关知识,一起来学习吧!
collections模块:实现了特定目标的容器,以提供Python标准内建容器 dict、list、set、tuple 的替代选择。
Counter:字典的子类,提供了可哈希对象的计数功能。
defaultdict:字典的子类,提供了一个工厂函数,为字典查询提供了默认值。
OrderedDict:字典的子类,保留了他们被添加的顺序。
namedtuple:创建命名元组子类的工厂函数。
deque:类似列表容器,实现了在两端快速添加(append)和弹出(pop)。
ChainMap:类似字典的容器类,将多个映射集合到一个视图里面。
Counter
Counter是一个dict子类,主要是用来对你访问的对象的频率进行计数。
>>> import collections >>> # 统计字符出现的次数 ... collections.Counter('hello world') Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1}) >>> # 统计单词个数 ... collections.Counter('hello world hello lucy'.split()) Counter({'hello': 2, 'world': 1, 'lucy': 1})
常用方法:
elements():返回一个迭代器,每个元素重复计算的个数,如果一个元素的计数小于1,就会被忽略。
most_common([n]):返回一个列表,提供n个访问频率最高的元素和计数
subtract([iterable-or-mapping]):从迭代对象中减去元素,输入输出可以是0或者负数
update([iterable-or-mapping]):从迭代对象计数元素或者从另一个 映射对象 (或计数器) 添加。
>>> c = collections.Counter('hello world hello lucy'.split()) >>> c Counter({'hello': 2, 'world': 1, 'lucy': 1}) >>> # 获取指定对象的访问次数,也可以使用get方法 ... c['hello'] 2 >>> # 查看元素 ... list(c.elements()) ['hello', 'hello', 'world', 'lucy'] >>> c1 = collections.Counter('hello world'.split()) >>> c2 = collections.Counter('hello lucy'.split()) >>> c1 Counter({'hello': 1, 'world': 1}) >>> c2 Counter({'hello': 1, 'lucy': 1}) >>> # 追加对象,+或者c1.update(c2) ... c1+c2 Counter({'hello': 2, 'world': 1, 'lucy': 1}) >>> # 减少对象,-或者c1.subtract(c2) ... c1-c2 Counter({'world': 1}) >>> # 清除 ... c.clear() >>> c Counter()
defaultdict
返回一个新的类似字典的对象。defaultdict 是内置 dict 类的子类。
class collections.defaultdict([default_factory[, ...]]) >>> d = collections.defaultdict() >>> d defaultdict(None, {}) >>> e = collections.defaultdict(str) >>> e defaultdict(<class 'str'>, {})
例子
defaultdict的一个典型用法是使用其中一种内置类型(如str、int、list或dict等)作为默认工厂,这些内置类型在没有参数调用时返回空类型。
>>> e = collections.defaultdict(str) >>> e defaultdict(<class 'str'>, {}) >>> e['hello'] '' >>> e defaultdict(<class 'str'>, {'hello': ''}) >>> # 普通字典调用不存在的键时,报错 ... e1 = {} >>> e1['hello'] Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'hello' 使用 int 作为 default_factory >>> fruit = collections.defaultdict(int) >>> fruit['apple'] = 2 >>> fruit defaultdict(<class 'int'>, {'apple': 2}) >>> fruit['banana'] # 没有对象时,返回0 0 >>> fruit defaultdict(<class 'int'>, {'apple': 2, 'banana': 0})
使用 list 作为 default_factory
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)] >>> d = collections.defaultdict(list) >>> for k,v in s: ... d[k].append(v) ... >>> d defaultdict(<class 'list'>, {'yellow': [1, 3], 'blue': [2, 4], 'red': [1]}) >>> d.items() dict_items([('yellow', [1, 3]), ('blue', [2, 4]), ('red', [1])]) >>> sorted(d.items()) [('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])] 使用 dict 作为 default_factory ```python >>> nums = collections.defaultdict(dict) >>> nums[1] = {'one':1} >>> nums defaultdict(, {1: {'one': 1}}) >>> nums[2] {} >>> nums defaultdict(, {1: {'one': 1}, 2: {}}) 使用 set 作为 default_factory ```python >>> types = collections.defaultdict(set) >>> types['手机'].add('华为') >>> types['手机'].add('小米') >>> types['显示器'].add('AOC') >>> types defaultdict(<class 'set'>, {'手机': {'华为', '小米'}, '显示器': {'AOC'}}) ## OrderedDict Python字典中的键的顺序是任意的,它们不受添加的顺序的控制。 collections.OrderedDict 类提供了保留他们添加顺序的字典对象。 ```python >>> o = collections.OrderedDict() >>> o['k1'] = 'v1' >>> o['k3'] = 'v3' >>> o['k2'] = 'v2' >>> o OrderedDict([('k1', 'v1'), ('k3', 'v3'), ('k2', 'v2')]) 如果在已经存在的 key 上添加新的值,将会保留原来的 key 的位置,然后覆盖 value 值。 ```python >>> o['k1'] = 666 >>> o OrderedDict([('k1', 666), ('k3', 'v3'), ('k2', 'v2')]) >>> dict(o) {'k1': 666, 'k3': 'v3', 'k2': 'v2'} ## namedtuple 三种定义命名元组的方法:第一个参数是命名元组的构造器(如下的:Person1,Person2,Person3) ```python >>> P1 = collections.namedtuple('Person1',['name','age','height']) >>> P2 = collections.namedtuple('Person2','name,age,height') >>> P3 = collections.namedtuple('Person3','name age height') 实例化命名元组 ```python >>> lucy = P1('lucy',23,180) >>> lucy Person1(name='lucy', age=23, height=180) >>> jack = P2('jack',20,190) >>> jack Person2(name='jack', age=20, height=190) >>> lucy.name # 直接通过 实例名.属性 来调用 'lucy' >>> lucy.age 23
deque
collections.deque 返回一个新的双向队列对象,从左到右初始化(用方法 append()),从 iterable(迭代对象)数据创建。如果 iterable 没有指定,新队列为空。
collections.deque 队列支持线程安全,对于从两端添加(append)或者弹出(pop),复杂度O(1)。
虽然 list 对象也支持类似操作,但是这里优化了定长操作(pop(0)、insert(0,v))的开销。
如果 maxlen 没有指定或者是 None ,deque 可以增长到任意长度。否则,deque 就限定到指定最大长度。一旦限定长度的 deque 满了,当新项加入时,同样数量的项就从另一端弹出。
支持的方法:
append(x):添加x到右端。
appendleft(x):添加x到左端。
clear():清除所有元素,长度变为0。
copy():创建一份浅拷贝。
count(x):计算队列中个数等于x的元素。
extend(iterable):在队列右侧添加iterable中的元素。
extendleft(iterable):在队列左侧添加iterable中的元素,注:在左侧添加时,iterable参数的顺序将会反过来添加。
index(x[,start[,stop]]):返回第 x 个元素(从 start 开始计算,在 stop 之前)。返回第一个匹配,如果没找到的话,抛出 ValueError 。
insert(i,x):在位置 i 插入 x 。注:如果插入会导致一个限长deque超出长度 maxlen 的话,就抛出一个 IndexError 。
pop():移除最右侧的元素。
popleft():移除最左侧的元素。
remove(value):移去找到的第一个 value。没有抛出ValueError。
reverse():将deque逆序排列。返回 None 。
maxlen:队列的最大长度,没有限定则为None。
>>> d = collections.deque(maxlen=10) >>> d deque([], maxlen=10) >>> d.extend('python') >>> [i.upper() for i in d] ['P', 'Y', 'T', 'H', 'O', 'N'] >>> d.append('e') >>> d.appendleft('f') >>> d.appendleft('g') >>> d.appendleft('h') >>> d deque(['h', 'g', 'f', 'p', 'y', 't', 'h', 'o', 'n', 'e'], maxlen=10) >>> d.appendleft('i') >>> d deque(['i', 'h', 'g', 'f', 'p', 'y', 't', 'h', 'o', 'n'], maxlen=10) >>> d.append('m') >>> d deque(['h', 'g', 'f', 'p', 'y', 't', 'h', 'o', 'n', 'm'], maxlen=10) ## ChainMap 问题背景是我们有多个字典或者映射,想把它们合并成为一个单独的映射,有人说可以用update进行合并,这样做的问题就是新建了一个数据结构以致于当我们对原来的字典进行更改的时候不会同步。如果想建立一个同步的查询方法,可以使用 ChainMap。 可以用来合并两个或者更多个字典,当查询的时候,从前往后依次查询。简单使用: ```python >>> d1 = {'apple':1,'banana':2} >>> d2 = {'orange':2,'apple':3,'pike':1} >>> combined1 = collections.ChainMap(d1,d2) >>> combined2 = collections.ChainMap(d2,d1) >>> combined1 ChainMap({'apple': 1, 'banana': 2}, {'orange': 2, 'apple': 3, 'pike': 1}) >>> combined2 ChainMap({'orange': 2, 'apple': 3, 'pike': 1}, {'apple': 1, 'banana': 2}) >>> for k,v in combined1.items(): ... print(k,v) ... orange 2 apple 1 pike 1 banana 2 >>> for k,v in combined2.items(): ... print(k,v) ... apple 3 banana 2 orange 2 pike 1 </code></pre> 有一个注意点就是当对ChainMap进行修改的时候总是只会对第一个字典进行修改,如果第一个字典不存在该键,会添加。 <pre><code class="language-python line-numbers">>>> d1 = {'apple':1,'banana':2} >>> d2 = {'orange':2,'apple':3,'pike':1} >>> c = collections.ChainMap(d1,d2) >>> c ChainMap({'apple': 1, 'banana': 2}, {'orange': 2, 'apple': 3, 'pike': 1}) >>> c['apple'] 1 >>> c['apple'] = 2 >>> c ChainMap({'apple': 2, 'banana': 2}, {'orange': 2, 'apple': 3, 'pike': 1}) >>> c['pike'] 1 >>> c['pike'] = 3 >>> c ChainMap({'apple': 2, 'banana': 2, 'pike': 3}, {'orange': 2, 'apple': 3, 'pike': 1}) 从原理上面讲,ChainMap 实际上是把放入的字典存储在一个队列中,当进行字典的增加删除等操作只会在第一个字典上进行,当进行查找的时候会依次查找,new_child() 方法实质上是在列表的第一个元素前放入一个字典,默认是{},而 parents 是去掉了列表开头的元素。 ```python >>> a = collections.ChainMap() >>> a['x'] = 1 >>> a ChainMap({'x': 1}) >>> b = a.new_child() >>> b ChainMap({}, {'x': 1}) >>> b['x'] = 2 >>> b ChainMap({'x': 2}, {'x': 1}) >>> b['y'] = 3 >>> b ChainMap({'x': 2, 'y': 3}, {'x': 1}) >>> a ChainMap({'x': 1}) >>> c = a.new_child() >>> c ChainMap({}, {'x': 1}) >>> c['x'] = 1 >>> c['y'] = 1 >>> c ChainMap({'x': 1, 'y': 1}, {'x': 1}) >>> d = c.parents >>> d ChainMap({'x': 1}) >>> d is a False >>> d == a True >>> a = {'x':1,'z':3} >>> b = {'y':2,'z':4} >>> c = collections.ChainMap(a,b) >>> c ChainMap({'x': 1, 'z': 3}, {'y': 2, 'z': 4}) >>> c.maps [{'x': 1, 'z': 3}, {'y': 2, 'z': 4}] >>> c.parents ChainMap({'y': 2, 'z': 4}) >>> c.parents.maps [{'y': 2, 'z': 4}] >>> c.parents.parents ChainMap({}) >>> c.parents.parents.parents ChainMap({})
到此这篇关于Python的collections模块真的很好用的文章就介绍到这了,更多相关Python的collections模块内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!
相关文章
- 这篇文章主要介绍了python-opencv-画外接矩形框的实例代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-04
Python astype(np.float)函数使用方法解析
这篇文章主要介绍了Python astype(np.float)函数使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-08- 2022虎年新年即将来临,小编为大家带来了一个利用Python编写的虎年烟花特效,堪称全网最绚烂,文中的示例代码简洁易懂,感兴趣的同学可以动手试一试...2022-02-14
- 在本篇文章里小编给大家分享的是一篇关于python中numpy.empty()函数实例讲解内容,对此有兴趣的朋友们可以学习下。...2021-02-06
python-for x in range的用法(注意要点、细节)
这篇文章主要介绍了python-for x in range的用法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-05-10- 这篇文章主要介绍了Python 图片转数组,二进制互转操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-09
- 这篇文章主要介绍了Python中的imread()函数用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
- 这篇文章主要介绍了python如何实现b站直播自动发送弹幕,帮助大家更好的理解和学习使用python,感兴趣的朋友可以了解下...2021-02-20
python Matplotlib基础--如何添加文本和标注
这篇文章主要介绍了python Matplotlib基础--如何添加文本和标注,帮助大家更好的利用Matplotlib绘制图表,感兴趣的朋友可以了解下...2021-01-26- 这篇文章主要介绍了解决python 使用openpyxl读写大文件的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-13
- 今天小编就为大家分享一篇python 计算方位角实例(根据两点的坐标计算),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-27
- 这篇文章主要介绍了使用Python的pencolor函数实现渐变色功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-09
- 在本篇文章里小编给大家整理的是一篇关于python中使用np.delete()的实例方法,对此有兴趣的朋友们可以学习参考下。...2021-02-01
- 这篇文章主要为大家详细介绍了python实现双色球随机选号,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-05-02
Python getsizeof()和getsize()区分详解
这篇文章主要介绍了Python getsizeof()和getsize()区分详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-20- 这篇文章主要介绍了python自动化办公操作PPT的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-05
- 这篇文章主要介绍了解决python 两个时间戳相减出现结果错误的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-12
- 这篇文章主要为大家详细介绍了python实现学生通讯录管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-25
- 这篇文章主要介绍了PyTorch一小时掌握之迁移学习篇,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-08
- 这篇文章主要介绍了python进行相关性分析并绘制散点图,具有一定借鉴价值,需要的朋友可以参考下,希望能够给你带来帮助...2021-09-18