浅析python内置模块collections


Posted in Python onNovember 15, 2019

collections是Python内建的一个集合模块,提供了许多有用的集合类。

1、namedtuple

python提供了很多非常好用的基本类型,比如不可变类型tuple,我们可以轻松地用它来表示一个二元向量。

>>> v = (2,3)

我们发现,虽然(2,3)表示出了一个向量的两个坐标,但是,如果没有额外说明,又很难直接看出这个元组是用来表示一个坐标的。

为此定义一个class又小题大做了,这时,namedtuple就派上用场了。

>>> from collections import namedtuple
>>> Vector = namedtuple('Vector', ['x', 'y'])
>>> v = Vector(2,3)
>>> v.x
2
>>> v.y
3

namedtuple是一个函数,它用来创建一个自定义的tuple对象,并且规定了tuple元素的个数,并可以用属性而不是索引来引用tuple的某个元素。

这样一来,我们用namedtuple可以很方便地定义一种数据类型,它具备tuple的不变性,又可以根据属性来引用,使用十分方便。

我们可以验证创建的Vector对象的类型。

>>> type(v)
<class '__main__.Vector'>
>>> isinstance(v, Vector)
True
>>> isinstance(v, tuple)
True

类似的,如果要用坐标和半径表示一个圆,也可以用namedtuple定义:

>>> Circle = namedtuple('Circle', ['x', 'y', 'r'])
# namedtuple('名称', [‘属性列表'])

2、deque

在数据结构中,我们知道队列和堆栈是两个非常重要的数据类型,一个先进先出,一个后进先出。在python中,使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。

deque是为了高效实现插入和删除操作的双向链表结构,非常适合实现队列和堆栈这样的数据结构。

>>> from collections import deque
>>> deq = deque([1, 2, 3])
>>> deq.append(4)
>>> deq
deque([1, 2, 3, 4])
>>> deq.appendleft(5)
>>> deq
deque([5, 1, 2, 3, 4])
>>> deq.pop()
4
>>> deq.popleft()
5
>>> deq
deque([1, 2, 3])

deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效地往头部添加或删除元素。

3、defaultdict

使用dict字典类型时,如果引用的key不存在,就会抛出KeyError。如果希望Key不存在时,返回一个默认值,就可以用defaultdict。

>>> from collections import defaultdict
>>> dd = defaultdict(lambda: 'defaultvalue')
>>> dd['key1'] = 'a'
>>> dd['key1']
'a'
>>> dd['key2'] # key2未定义,返回默认值
'defaultvalue'

注意默认值是调用函数返回的,而函数在创建defaultdict对象时传入。

除了在Key不存在时返回默认值,defaultdict的其他行为跟dict是完全一样的。

4、OrderedDict

使用dict时,key是无序的。在对dict做迭代时,我们无法确定key的顺序。

但是如果想要保持key的顺序,可以用OrderedDict。

>>> from collections import OrderedDict
>>> d = dict([('a', 1), ('b', 2), ('c', 3)])
>>> d # dict的Key是无序的
{'a': 1, 'c': 3, 'b': 2}
>>> od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
>>> od # OrderedDict的Key是有序的
OrderedDict([('a', 1), ('b', 2), ('c', 3)])

注意,OrderedDict的key会按照插入的顺序排列,不是key本身排序

>>> od = OrderedDict()
>>> od['z'] = 1
>>> od['y'] = 2
>>> od['x'] = 3
>>> list(od.keys()) # 按照插入的Key的顺序返回
['z', 'y', 'x']

OrderedDict可以实现一个FIFO(先进先出)的dict,当容量超出限制时,先删除最早添加的key。

from collections import OrderedDict
class LastUpdatedOrderedDict(OrderedDict):
  def __init__(self, capacity):
    super(LastUpdatedOrderedDict, self).__init__()
    self._capacity = capacity
  def __setitem__(self, key, value):
    containsKey = 1 if key in self else 0
    if len(self) - containsKey >= self._capacity:
      last = self.popitem(last=False)
      print('remove:', last)
    if containsKey:
      del self[key]
      print('set:', (key, value))
    else:
      print('add:', (key, value))
    OrderedDict.__setitem__(self, key, value)

5、ChainMap

ChainMap可以把一组dict串起来并组成一个逻辑上的dict。ChainMap本身也是一个dict,但是查找的时候,会按照顺序在内部的dict依次查找。

什么时候使用ChainMap最合适?举个例子:应用程序往往都需要传入参数,参数可以通过命令行传入,可以通过环境变量传入,还可以有默认参数。我们可以用ChainMap实现参数的优先级查找,即先查命令行参数,如果没有传入,再查环境变量,如果没有,就使用默认参数。

下面的代码演示了如何查找user和color这两个参数。

from collections import ChainMap
import os, argparse
# 构造缺省参数:
defaults = {
  'color': 'red',
  'user': 'guest'
}
# 构造命令行参数:
parser = argparse.ArgumentParser()
parser.add_argument('-u', '--user')
parser.add_argument('-c', '--color')
namespace = parser.parse_args()
command_line_args = { k: v for k, v in vars(namespace).items() if v }
# 组合成ChainMap:
combined = ChainMap(command_line_args, os.environ, defaults)
# 打印参数:
print('color=%s' % combined['color'])
print('user=%s' % combined['user'])

没有任何参数时,打印出默认参数:

$ python3 use_chainmap.py 
color=red
user=guest

当传入命令行参数时,优先使用命令行参数:

$ python3 use_chainmap.py -u bob
color=red
user=bob

同时传入命令行参数和环境变量,命令行参数的优先级较高:

$ user=admin color=green python3 use_chainmap.py -u bob
color=green
user=bob

6、Counter

Counter是一个简单的计数器,例如,统计字符出现的个数:

from collections import Counter
>>> s = 'abbcccdddd'
>>> Counter(s)
Counter({'d': 4, 'c': 3, 'b': 2, 'a': 1})

Counter实际上也是dict的一个子类。

7、小结

collections模块提供了一些有用的集合类,可以根据需要选用。

以上所述是小编给大家介绍的python内置模块collections,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
用Python写的图片蜘蛛人代码
Aug 27 Python
在Linux下调试Python代码的各种方法
Apr 17 Python
Python合并字符串的3种方法
May 21 Python
网红编程语言Python将纳入高考你怎么看?
Jun 07 Python
python清除函数占用的内存方法
Jun 25 Python
Python3 利用requests 库进行post携带账号密码请求数据的方法
Oct 26 Python
实例详解python函数的对象、函数嵌套、名称空间和作用域
May 31 Python
Python Numpy计算各类距离的方法
Jul 05 Python
Pyecharts绘制全球流向图的示例代码
Jan 08 Python
Python对wav文件的重采样实例
Feb 25 Python
python中sklearn的pipeline模块实例详解
May 21 Python
基于K.image_data_format() == 'channels_first' 的理解
Jun 29 Python
Python树莓派学习笔记之UDP传输视频帧操作详解
Nov 15 #Python
Python numpy数组转置与轴变换
Nov 15 #Python
python修改文件内容的3种方法详解
Nov 15 #Python
Python实现基于socket的udp传输与接收功能详解
Nov 15 #Python
python根据文本生成词云图代码实例
Nov 15 #Python
解决django后台管理界面添加中文内容乱码问题
Nov 15 #Python
python中的TCP(传输控制协议)用法实例分析
Nov 15 #Python
You might like
jQuery+PHP实现的掷色子抽奖游戏实例
2015/01/04 PHP
php使用socket post数据到其它web服务器的方法
2015/06/02 PHP
PHP检查文件是否存在,不存在自动创建及读取文件内容操作示例
2020/01/23 PHP
javascript call和apply方法
2008/11/24 Javascript
jquery 子窗口操作父窗口的代码
2009/09/21 Javascript
javascript之典型高阶函数应用介绍二
2013/01/10 Javascript
JSON+JavaScript处理JSON的简单例子
2013/03/20 Javascript
JS.elementGetStyle(element, style)应用示例
2013/09/24 Javascript
jquery使用jxl插件导出excel示例
2014/04/14 Javascript
Node.js中安全调用系统命令的方法(避免注入安全漏洞)
2014/12/05 Javascript
js判断上传文件后缀名是否合法
2016/01/28 Javascript
更高效的使用JQuery 这里总结了8个小技巧
2016/04/13 Javascript
JS定时器使用,定时定点,固定时刻,循环执行详解
2016/05/31 Javascript
jquery实现网页定位导航
2016/08/23 Javascript
KnockoutJS 3.X API 第四章之表单value绑定
2016/10/10 Javascript
vue iview实现动态路由和权限验证功能
2018/04/17 Javascript
jQuery实现轮播图源码
2019/10/23 jQuery
Javascript模块化机制实现原理详解
2020/04/02 Javascript
详解JavaScript作用域 闭包
2020/07/29 Javascript
Vue实现简单的拖拽效果
2020/08/25 Javascript
js观察者模式的弹幕案例
2020/11/23 Javascript
[01:08]DOTA2“血战之命”预告片
2017/08/12 DOTA
[40:19]2018完美盛典CS.GO表演赛
2018/12/17 DOTA
[52:05]EG vs OG 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/18 DOTA
Python脚本实现虾米网签到功能
2016/04/12 Python
[原创]教女朋友学Python3(二)简单的输入输出及内置函数查看
2017/11/30 Python
python3 图片 4通道转成3通道 1通道转成3通道 图片压缩实例
2019/12/03 Python
python中id函数运行方式
2020/07/03 Python
amazeui树节点自动展开折叠面板并选中第一个树节点的实现
2020/08/24 HTML / CSS
莫斯科绝对前卫最秘密的商店:SVMoscow
2017/10/23 全球购物
瑜伽灵感珠宝:Satya Jewelry
2018/01/06 全球购物
数控专业自荐书范文
2014/03/16 职场文书
写得不错的求职信范文
2014/07/11 职场文书
个人更名证明
2015/06/23 职场文书
承诺书的签字人,需不需要承担相应的责任?
2019/07/09 职场文书
Java实现多线程聊天室
2021/06/26 Java/Android