"在内置数据类型(dict、list、set、tuple)的基础上,collections模块提供了几个额外的数据类型:

  • namedtuple:生成可以使用名字来访问元素内容的tuple,通常用来增强代码的可读性, 在访问一些tuple类型的数据时尤其好用.
  • deque:双端队列,可以快速的从另外一侧追加和推出对象.
  • Counter:计数器,主要用来计数.
  • OrderedDict:有序字典.
  • defaultdict:带有默认值的字典.

@


namedtuple

首先,我们知道tuple可以表示不变集合,例如一个点的二维坐标可以表示为:

>>> p = (1, 2)

可是,看到(1, 2),我们很难分辨出这个tuple是用来表示一个坐标的.

这时,namedtuple就派上用场了:

>>> from collections import namedtuple
>>> Ponint = namedtuple('Ponint', ['x', 'y'])
>>> p = Ponint(1, 2)
>>> p.x
1
>>> p.y
2

再比如,有这样一个数据结构:每一个对象都是拥有三个元素的tuple.

使用namedtuple方法就可以方便的通过tuple来生成可读性更高也更好用的数据结构.

from collections import namedtuple

userinfo = [
("花千骨", "洪荒之力", "白子画"),
("白浅", "玉清昆仑扇", "夜华"),
("锦觅", "翊圣玄冰", "旭凤")
] Userinfo = namedtuple('Userinfo', ["姓名", "必杀技", "男朋友"])
[print(Userinfo._make(ui)) for ui in userinfo] """打印结果如下:
Userinfo(姓名='花千骨', 必杀技='洪荒之力', 男朋友='白子画')
Userinfo(姓名='白浅', 必杀技='玉清昆仑扇', 男朋友='夜华')
Userinfo(姓名='锦觅', 必杀技='翊圣玄冰', 男朋友='旭凤')
"""

deque

所谓的单端队列,就是一端进,另一端出.

所谓的双端队列,就是两端都可以进出.

deque其实是double-ended queue的缩写,翻译过来就是双端队列.

deque最大的好处就是实现了从队列头部快速增加和取出对象:.popleft(), .appendleft()

你可能会说,原生的list也可以从头部添加和取出对象啊?就像这样:

lst.insert(0, 'a')
lst.pop(0)

但是,我们得注意了,list对象的这两种用法的时间复杂度为O(n),也就是说随着元素数量的增加,耗时呈线性上升.

而使用deque对象则是O(1)的复杂度,所以当你的代码有这样的需求的时候,一定要记得使用deque.

deque与list的效率问题

·

  • 使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除的效率会很低.
  • 在使用insert、remove方法时,deque的平均效率要远高于list.
  • list根据索引查某个值的效率要高于deque.
  • append和pop方法对于列表的效率没有影响.

示例 deque两端进出

>>> from collections import deque
>>> dq = deque([1, 2, 3])
>>> dq.append('z')
>>> dq.appendleft('a') # 从头部添加元素
>>> dq.pop()
'z'
>>> dq.popleft() # 从头部弹出元素
'a'

作为一个双端队列,deque还提供了其它的好用的方法,比如rotate.

下面是一个有趣的例子,主要使用了deque的rotate方法来实现一个无限循环的加载动画.

from collections import deque
import sys
import time running = deque('>---------------------')
while 1:
print('\r', ''.join(running), end='')
running.rotate(1)
sys.stdout.flush()
time.sleep(0.2) # 一个无限循环的跑马灯
# ------------>--------

Counter

Counter类的目的是用来跟踪值出现的次数.

Counter是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,计数作为value,计数值可以是任意的Interger(包括0和负数).

Counter类和其它语言的bags或multisets很相似.

示例 使用Counter模块统计一段句子里面所有字符出现次数

from collections import Counter

s = '''
A Counter is a dict subclass for counting hashable objects.
It is an unordered collection where elements are stored as dictionary keys and
their counts are stored as dictionary values.
Counts are allowed to be any integer value including zero or negative counts.
The Counter class is similar to bags or multisets in other languages.
'''.lower() c = Counter(s)
# 获取出现频率最高的4个字符
print(c.most_common(4)) # [(' ', 74), ('e', 32), ('s', 25), ('a', 24)]

OrderedDict

在Python中,dict这个数据结构由于hash的特性,是无序的,这在有的时候会给我们带来一些麻烦.

幸运的是,collections模块为我们提供了OrderedDict,当你要获得一个有序的字典对象时,用它就对了.

Python3.6版本以后的字典是有序的了.

简单示例

>>> 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
>>> od.keys() # 按照插入的Key的顺序返回
['z', 'y', 'x']

defaultdict

一个示例

·

有这么一个集合:[1, 2, 3, 4, 5, 7, 8, 9]

将所有小于5的值保存至字典的第一个key中,大于5的值保存至第二个key中.

·

我们先来看看dict如何实现:

lst = [1, 2, 3, 4, 5, 7, 8, 9]
dct = {}
for i in lst:
key = 'k1' if i < 5 else 'k2'
dct.setdefault(key, []).append(i)

再来看看defaultdict如何实现:

from collections import defaultdict

lst = [1, 2, 3, 4, 5, 7, 8, 9]
dd = defaultdict(list) for i in lst:
key = 'k1' if i < 5 else 'k2'
dd[key].append(i) # defaultdict(<class 'list'>, {'k1': [1, 2, 3, 4], 'k2': [5, 7, 8, 9]})

还有,在使用Python原生的数据结构dict的时候,如果用d[key]这样的方式访问, 当指定的key不存在时,是会抛出KeyError异常的.

但是,如果使用defaultdict,只要你传入一个默认的工厂方法,那么请求一个不存在的key时, 便会调用这个工厂方法使用其结果来作为这个key的默认值.

>>> from collections import defaultdict
>>> dd = defaultdict(lambda: 'N/A')
>>> dd['name'] = "花千骨"
>>> dd['name']
'花千骨'
>>> dd['sex'] #'sex'不存在,将返回默认值
'N/A'

上面只是非常简单的介绍了一下collections模块的主要内容,主要目的就是当你碰到适合使用它们的场所时,能够记起并使用它们,起到事半功倍的效果.

如果想要对它们有一个更全面和深入了解的话,建议阅读官方文档和模块源码,Go.



"

【Python collections】的更多相关文章

  1. 【Python数据分析】Python3多线程并发网络爬虫-以豆瓣图书Top250为例

    基于上两篇文章的工作 [Python数据分析]Python3操作Excel-以豆瓣图书Top250为例 [Python数据分析]Python3操作Excel(二) 一些问题的解决与优化 已经正确地实现 ...

  2. 【Python数据分析】Python3操作Excel(二) 一些问题的解决与优化

    继上一篇[Python数据分析]Python3操作Excel-以豆瓣图书Top250为例 对豆瓣图书Top250进行爬取以后,鉴于还有一些问题没有解决,所以进行了进一步的交流讨论,这期间得到了一只尼玛 ...

  3. 利用Dnspod api批量更新添加DNS解析【python脚本】 - 推酷

    利用Dnspod api批量更新添加DNS解析[python脚本] - 推酷 undefined

  4. 【python进阶】详解元类及其应用2

    前言 在上一篇文章[python进阶]详解元类及其应用1中,我们提到了关于元类的一些前置知识,介绍了类对象,动态创建类,使用type创建类,这一节我们将继续接着上文来讲~~~ 5.使⽤type创建带有 ...

  5. 【python进阶】Garbage collection垃圾回收2

    前言 在上一篇文章[python进阶]Garbage collection垃圾回收1,我们讲述了Garbage collection(GC垃圾回收),画说Ruby与Python垃圾回收,Python中 ...

  6. 【python进阶】深入理解系统进程2

    前言 在上一篇[python进阶]深入理解系统进程1中,我们讲述了多任务的一些概念,多进程的创建,fork等一些问题,这一节我们继续接着讲述系统进程的一些方法及注意点 multiprocessing ...

  7. 【python图像处理】图像的缩放、旋转与翻转

    [python图像处理]图像的缩放.旋转与翻转 图像的几何变换,如缩放.旋转和翻转等,在图像处理中扮演着重要的角色,python中的Image类分别提供了这些操作的接口函数,下面进行逐一介绍. 1.图 ...

  8. 【Python 开发】Python目录

    目录: [Python开发]第一篇:计算机基础 [Python 开发]第二篇 :Python安装 [Python 开发]第三篇:python 实用小工具

  9. 【Python教程】《零基础入门学习Python》(小甲鱼)

    [Python教程]<零基础入门学习Python>(小甲鱼) 讲解通俗易懂,诙谐. 哈哈哈. https://www.bilibili.com/video/av27789609

随机推荐

  1. 理解 Oracle 多租户体系中(12c,18c,19c)创建用户作用域范围

    本篇探讨以下几个问题:你可提前猜测下面6个场景语句中,哪几个可以成功创建用户? 1. 在CDB级别中创建公共用户,不带 container 子句的效果: 2. 在CDB级别中创建公共用户,带 cont ...

  2. SpringBoot多数据源:动态数据源

    目录 1. 引言 2. 动态数据源流程说明 3. 实现动态数据源 3.1 说明及数据源配置 3.1.1 包结构说明 3.1.2 数据库连接信息配置 3.1.3 数据源配置 3.2 动态数据源设置 3. ...

  3. Java世界最常用的工具类库

    Apache Commons Apache Commons有很多子项目,常用的项目如下 BeanUtils 提供了一系列对java bean的操作,读取和设置属性值等 map和bean的互相转换 我们 ...

  4. 如何面试QA(面试官角度)

    面试是一对一 或者多对一的沟通,是和候选人 互相交换信息.平等的. 面试的目标是选择和雇佣最适合的人选.是为了完成组织目标.协助人力判断候选人是否合适空缺职位. 面试类型: (1)预判面试(查看简历后 ...

  5. Windows下解决github push failed (remote: Permission to userA/XXXX.git denied to userB.) 上传gitHub失败报错

    Windows环境下解决 github push failed (remote: Permission to userA/XXXX.git denied to userB.) · 初学GitHub的朋 ...

  6. sql查询——子查询

    -- 子查询 -- 一句查询语句内,再套一句查询语句 ,叫子查询 -- 查询班级类身高最高的人的名字 select name from students where high=(select max( ...

  7. python中乱码怎么由来与解决方法

    前言曾几何时 Python 中文乱码的问题困扰了我很多很多年,每次出现中文乱码都要去网上搜索答案,虽然解决了当时遇到的问题但下次出现乱码的时候又会懵逼,究其原因还是知其然不知其所以然.现在有的小伙伴为 ...

  8. ConsoleWindow中的双击日志定位

    很多项目都有自己重写Debug.Log的习惯,难免会遇到在Unity的Console窗口中双击日志, 但是没法直接跳转到想要看到的代码那一行的时候,解决办法有以下2种: 将自己封装的日志类制作成DLL ...

  9. 在Unity3d中使用Google.ProtocolBuffers

    通过Nuget下载Google.ProtocolBuffers,在目录中找到net35下的文件,放入unity3d中作为插件 PersonMessage.Builder personBuilder = ...

  10. HTTP请求消息的数据格式

    servletRequest获取请求消息 Request 分为4部分1.请求行 格式:请求方式 请求url 请求协议/版本GET /login.html HTTP/1.1 特点:行和头之间没有任何分隔 ...