鱼C论坛

 找回密码
 立即注册
查看: 3702|回复: 1

[技术交流] <标准库> collections模块

[复制链接]
发表于 2015-3-21 13:46:36 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
Python作为一个“自带电池”的编程语言,标准库里面拥有非常多好用的模块。比如今天想给大家 介绍的 collections 就是一个非常好的例子

collections模块基本介绍

我们都知道,Python拥有一些内置的数据类型,比如str, int, list, tuple, dict等, collections模块在这些内置数据类型的基础上,提供了几个额外的数据类型:

1. namedtuple(): 生成可以使用名字来访问元素内容的tuple子类
2. deque: 双端队列,可以快速的从另外一侧追加和推出对象
3. Counter: 计数器,主要用来计数
4. OrderedDict: 有序字典
5. defaultdict: 带有默认值的字典

#########################

namedtuple()
namedtuple主要用来产生可以使用名称来访问元素的数据对象,通常用来增强代码的可读性, 在访问一些tuple类型的数据时尤其好用。
举个栗子
  1. """
  2. 比如我们用户拥有一个这样的数据结构,每一个对象是拥有三个元素的tuple。
  3. 使用namedtuple方法就可以方便的通过tuple来生成可读性更高也更好用的数据结构。
  4. """
  5. import collections
  6. websites = [
  7.     ('Sohu', 'http://www.google.com/', '张朝阳'),
  8.     ('Sina', 'http://www.sina.com.cn/', '王志东'),
  9.     ('163', 'http://www.163.com/', '丁磊')
  10. ]
  11. Website = collections.namedtuple('Website', ['name', 'url', 'founder'])
  12. for i in websites:
  13.     website = Website._make(i)
  14.     print(website)
复制代码
  1. Website(name='Sohu', url='http://www.google.com/', founder='张朝阳')
  2. Website(name='Sina', url='http://www.sina.com.cn/', founder='王志东')
  3. Website(name='163', url='http://www.163.com/', founder='丁磊')
复制代码


deque
deque其实是 double-ended-queue 的缩写,翻译过来就是双端队列,它最大的好处就是实现了从队列 头部快速增加和取出对象: .popleft(), .appendleft() 。
你可能会说,原生的list也可以从头部添加和取出对象啊?就像这样:
  1. l.insert(0, v)
  2. l.pop(0)
复制代码
但是值得注意的是,list对象的这两种用法的时间复杂度是 O(n) ,也就是说随着元素数量的增加耗时呈 线性上升。而使用deque对象则是 O(1) 的复杂度,所以当你的代码有这样的需求的时候, 一定要记得使用deque。
作为一个双端队列,deque还提供了一些其他的好用方法,比如 rotate 等。
举个栗子
  1. """
  2. 下面这个是一个有趣的例子,主要使用了deque的rotate方法来实现了一个无限循环的加载动画
  3. """
  4. import sys
  5. import time
  6. import collections
  7. fancy_loading = collections.deque('>--------------------')
  8. while True:
  9.     print('\r%s' % ''.join(fancy_loading), end ='')
  10.     fancy_loading.rotate(1)
  11.     sys.stdout.flush()
  12.     time.sleep(0.08)
  13. # 结果是什么, 大家自己试试
复制代码


Counter
计数器是一个非常常用的功能需求,collections也贴心的为你提供了这个功能。
举个栗子
  1. """
  2. 下面这个例子就是使用Counter模块统计一段句子里面所有字符出现次数
  3. """
  4. import collections
  5. 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()
  6. c = collections.Counter(s)
  7. # 获取出现频率最高的5个字符
  8. print(c.most_common(5))
复制代码
  1. [(' ', 54), ('e', 32), ('s', 25), ('a', 24), ('t', 24)]
复制代码


OrderedDict
在Python中,dict这个数据结构由于hash的特性,是无序的,这在有的时候会给我们带来一些麻烦, 幸运的是,collections模块为我们提供了OrderedDict,当你要获得一个有序的字典对象时,用它就对了。
举个栗子
  1. import collections
  2. items = (
  3.     ('A', 1),
  4.     ('B', 2),
  5.     ('C', 3)
  6. )
  7. regular_dict = dict(items)
  8. ordered_dict = collections.OrderedDict(items)
  9. print('Regular Dict:')
  10. for k, v in regular_dict.items():
  11.     print(k, v)
  12. print('Ordered Dict:')
  13. for k, v in ordered_dict.items():
  14.     print(k, v)
复制代码
  1. Regular Dict:
  2. A 1
  3. C 3
  4. B 2
  5. Ordered Dict:
  6. A 1
  7. B 2
  8. C 3
复制代码


defaultdict
我们都知道,在使用Python原生的数据结构dict的时候,如果用 d[key] 这样的方式访问, 当指定的key不存在时,是会抛出KeyError异常的。
但是,如果使用defaultdict,只要你传入一个默认的工厂方法,那么请求一个不存在的key时, 便会调用这个工厂方法使用其结果来作为这个key的默认值。
代码如下:
  1. import collections
  2. members = [
  3.     # Age, name
  4.     ['male', 'John'],
  5.     ['male', 'Jack'],
  6.     ['female', 'Lily'],
  7.     ['male', 'Pony'],
  8.     ['female', 'Lucy'],
  9. ]
  10. result = collecttios.defaultdict(list)
  11. for sex, name in members:
  12.     result[sex].append(name)
  13. print(result)
复制代码
  1. defaultdict(<type 'list'>, {'male': ['John', 'Jack', 'Pony'], 'female': ['Lily', 'Lucy']})
复制代码


上面只是非常简单的介绍了一下collections模块的主要内容,主要目的就是当你碰到适合使用 它们的场所时,能够记起并使用它们,起到事半功倍的效果。
如果要对它们有一个更全面和深入了解的话,还是建议阅读官方文档和模块源码。

评分

参与人数 2荣誉 +6 鱼币 +6 贡献 +3 收起 理由
拈花小仙 + 5 + 5 + 3 感谢楼主无私奉献!
微逻辑 + 1 + 1 热爱鱼C^_^

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-3-21 14:44:57 | 显示全部楼层
没有放到专辑里,我就说怎么看到你发贴,结果木有提示我专辑更新了~

评分

参与人数 1荣誉 +3 鱼币 +5 收起 理由
戴宇轩 + 3 + 5 谢谢提醒!^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-27 14:01

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表