官方文档:https://yiyibooks.cn/xx/python_352/library/collections.html

参考:

  https://blog.csdn.net/songfreeman/article/details/50502194

  https://www.cnblogs.com/Eva-J/articles/7228075.html#_label15

Collections模块

 在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。

  1.namedtuple: 生成可以使用名字来访问元素内容的tuple

  2.deque: 双端队列,可以快速的从另外一侧追加和推出对象

  3.Counter: 计数器,主要用来计数

  4.OrderedDict: 有序字典

  5.defaultdict: 带有默认值的字典

1. Counter

Counter 作为字典(dict)的一个子类用来进行hashtable计数,将元素进行数量统计、计数后返回一个字典,键值为元素:值为元素个数

s = 'abcbcaccbbad'
l = ['a','b','c','c','a','b','b']
d = {'2': 3, '3': 2, '17': 2}
# Counter 获取各元素的个数,返回字典
print(Counter(s)) # Counter({'c': 4, 'b': 4, 'a': 3})
print(Counter(l)) # Counter({'b': 3, 'a': 2, 'c': 2})
print(Counter(d)) # Counter({3: 3, 2: 2, 17: 1})

方法:
 most_common

# most_common(int) 按照元素出现的次数进行从高到低的排序,返回前int个元素的字典
m1 = Counter(s)
print(m1) # Counter({'c': 4, 'b': 4, 'a': 3, 'd': 1})
print(m1.most_common(3)) # [('c', 4), ('b', 4), ('a', 3)]

 elements

# elements 返回经过计数器Counter后的元素,返回的是一个迭代器
e1 = Counter(s)
print(''.join(sorted(e1.elements()))) # aaabbbbcccc
e2 = Counter(d)
print(sorted(e2.elements())) # ['17', '17', '2', '2', '2', '3', '3'] 字典返回value个key

 update

# update 和set集合的update一样,对集合进行并集更新
u1 = Counter(s)
u1.update('123a')
print(u1) # Counter({'a': 4, 'c': 4, 'b': 4, '1': 1, '3': 1, '2': 1})

 substract

# substract 和update类似,只是update是做加法,substract做减法,从另一个集合中减去本集合的元素,
sub1 = 'which'
sub2 = 'whatw'
subset = Counter(sub1)
print(subset) # Counter({'h': 2, 'i': 1, 'c': 1, 'w': 1})
subset.subtract(Counter(sub2))
print(subset) # Counter({'c': 1, 'i': 1, 'h': 1, 'a': -1, 't': -1, 'w': -1}) sub1中的h变为2,sub2中h为1,减完以后为1

 iteritems
  与字典dict的items类似,返回由Counter生成的字典的所有item,只是在Counter中此方法返回的是一个迭代器,而不是列表
 iterkeys
  与字典dict的keys方法类似,返回由Counter生成的字典的所有key,只是在Counter中此方法返回的是一个迭代器,而不是列表
 itervalues
  与字典dict的values方法类似,返回由Counter生成的字典的所有value,只是在Counter中此方法返回的是一个迭代器,而不是列表

2.deque

deque 包含在文件_collections.py中,属于高性能的数据结构(High performance data structures)之一.可以从两端添加和删除元素,常用的结构是它的简化版。

deque常用方法:
 deque

str1 = 'abc123cd'
dq = deque(str1)
print(dq) # deque(['a', 'b', 'c', '1', '2', '3', 'c', 'd'])

 append
  队列右边添加元素
 appendleft
  队列左边添加元素

dq = deque('abc123')
dq.append('right')
dq.appendleft('left')
print(dq) # deque(['left', 'a', 'b', 'c', '1', '2', '3', 'right'])

 clear
  clear 清空队列中的所有元素
 count
  count(value)  返回队列中包含value的个数,结果类型为 integer
 extend
  extend 队列右边扩展,可以是列表、元组或字典,如果是字典则将字典的key加入到deque
 extendleft
  extendleft  同extend, 在左边扩展

dq = deque('abc123')
dq.extend({1:10,2:20})
dq.extendleft('L')
print(dq) # deque(['L', 'a', 'b', 'c', '1', '2', '3', 1, 2])

 pop
  pop  移除并且返回队列右边的元素
 popleft
  popleft 移除并且返回队列左边的元素
 remove
  remove(value) 移除队列第一个出现的元素(从左往右开始的第一次出现的元素value)
 reverse
  reverse  队列的所有元素进行反转
 rotate
  rotate(n) 对队列的数进行移动,若n<0,则往左移动即将左边的第一个移动到最后,移动n次,n>0 往右移动

dq = deque([1,2,3,4,5])
dq.rotate(-1) # 左移,1往左移动一位到5后面
print(dq)

3.defaultdict

默认字典,是字典的一个子类,继承有字典的方法和属性,默认字典在进行定义初始化的时候可以指定字典值的默认类型

dic = collections.defaultdict(dict)
dic['k1'].update({'k2':'aaa'})
print(dic)

  我们看上面的例子,字典dic在定义的时候就定义好了值为字典类型,虽然现在字典中还没有键值 k1,但仍然可以执行字典的update方法. 这种操作方式在传统的字典类型中是无法实现的,必须赋值以后才能进行值得更新操作,否则会报错。
我看看一下传统的字典类型

b = dict()

b['k1'].append('2')

# TypeError: 'type' object is not iterable

注意:初始化时,指定的类型一般是方法不是实例!!!

# 正确的
dic1 = collections.defaultdict(dict) dic2 = collections.defaultdict(list) dic3 = collections.defaultdict(lambda: 'N/A')

# 错误的
dic4 = collections.defaultdict(list())

 另一个注意点:当从字典中获取一个未定义 或 不存在的key时,value会以默认值给出!不会报错!!!

>>> from collections import defaultdict
>>> dd = defaultdict(lambda: 'N/A')
>>> dd['key1'] = 'abc'
>>> dd['key1'] # key1存在
'abc'
>>> dd['key2'] # key2不存在,返回默认值
'N/A'

4.OrderedDict

OrderDict 叫做有序字典,也是字典类型(dict)的一个子类,是对字典的一个补充。 前面我们说过,字典类型是一个无序的集合,如果要想将一个传统的字典类型进行排序一般会怎么做了,我们可能会将字典的键值取出来做排序后在根据键值来进行有序的输出,我们看下面的一个例子:

# 定义传统字典
dic1 = dict()
# 按顺序添加字典内容
dic1['a'] = '123'
dic1['b'] = 'jjj'
dic1['c'] = '394'
dic1['d'] = '999'
print(dic1) # 结果: {'a': '123', 'c': '394', 'b': 'jjj', 'd': '999'}
# 排序
dic1_key_list = []
for k in dic1.keys():
dic1_key_list.append(k)
dic1_key_list.sort()
for key in dic1_key_list:
print('dic1字典排序结果 %s:%s' %(key,dic1[key]))

以上为定义传统字典类型时的一个简单排序过程。 如果我们定义一个有序字典时,将不用再如此麻烦, 字典顺序将按照录入顺序进行排序且不会改变。

# 定义有序字典
dic2 = OrderedDict()
dic2['a'] = '123'
dic2['b'] = 'jjj'
dic2['c'] = 'abc'
dic2['d'] = '999'
for k, v in dic2.iteritems():
print('有序字典:%s:%s' %(k,v))

其他对比示例:

示例:
import collections
print "Regular dictionary"
d={}
d['a']='A'
d['b']='B'
d['c']='C'
for k,v in d.items():
print k,v print "\nOrder dictionary"
d1 = collections.OrderedDict()
d1['a'] = 'A'
d1['b'] = 'B'
d1['c'] = 'C'
d1['1'] = '1'
d1['2'] = '2'
for k,v in d1.items():
print k,v 输出:
Regular dictionary
a A
c C
b B Order dictionary
a A
b B
c C
1 1
2 2
# 可以看到,同样是保存了ABC等几个元素,但是使用OrderedDict会根据放入元素的先后顺序进行排序。所以输出的值是排好序的。
# OrderedDict对象的字典对象,如果其顺序不同那么Python也会把他们当做是两个不同的对象,请看示例:
print 'Regular dictionary:'
d2={}
d2['a']='A'
d2['b']='B'
d2['c']='C' d3={}
d3['c']='C'
d3['a']='A'
d3['b']='B' print d2 == d3 print '\nOrderedDict:'
d4=collections.OrderedDict()
d4['a']='A'
d4['b']='B'
d4['c']='C' d5=collections.OrderedDict()
d5['c']='C'
d5['a']='A'
d5['b']='B' print d1==d2 输出:
Regular dictionary:
True OrderedDict:
False # 有序排序:
dd = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}
#按key排序
kd = collections.OrderedDict(sorted(dd.items(), key=lambda t: t[0]))
print kd
#按照value排序
vd = collections.OrderedDict(sorted(dd.items(),key=lambda t:t[1]))
print vd #输出
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

5.namedtuple

标准的tuple类型使用数字索引来访问元素,

bob = ('Bob', 30, 'male')
print('Representation:', bob) jane = ('Jane', 29, 'female')
print('\nField by index:', jane[0]) print('\nFields by index:')
for p in [bob, jane]:
print('%s is a %d year old %s' % p)

这种对于标准的元组访问,我们需要知道元素对应下标索引值,但当元组的元素很多时,我们可能无法知道每个元素的具体索引值,这个时候就是可命名元组登场的时候了。
namedtuple 的创建是由自己的类工厂namedtuple()进行创建,而不是由标准的元组来进行实例化,通过namedtuple()创建类的参数包括类名称和一个包含元素名称的字符串

from collections import namedtuple

#创建一个namedtuple 类,类名称为Person,并赋给变量P
P = namedtuple('Person', 'name,age,gender')
print('Type of Person:', type(P)) # Type of Person: <class 'type'> #通过Person类实例化一个对象bob
bob = P(name='Bob', age=30, gender='male')
print('\nRepresentation:', bob) # Representation: Person(name='Bob', age=30, gender='male') #通过Person类实例化一个对象jane
jane = P(name='Jane', age=29, gender='female')
print('\nField by name:', jane.name) # Field by name: Jane print('\nFields by index:')
for p in [bob, jane]:
print('%s is a %d year old %s' % p)
# Fields by index:
# Bob is a 30 year old male
# Jane is a 29 year old female

通过上面的实例可以看出,我们通过namedtuple()创建了一个Person的类,并复制给P变量,Person的类成员包括name,age,gender,并且顺序已经定了,在实例化zhangsan这个对象的时候,对张三的属性进行了定义。这样我们在访问zhangsan这个元组的时候就可以通过张三的属性来复制(zhangsan.name、zhangsan.age等)。这样就算这个元组有1000个元素我们都能通过元素的名称来访问而不用考虑元素的下标索引值。
非法的参数值
使用namedtuple()来创建类的时候,传递的成员属性参数名称不能非法(不能为系统参数名称),且参数名称不能重复,否则会报值错误

# 参数字段的名称非法,包含系统名称class
try:
p = namedtuple('Person','age,name,class,gender')
print(p._fields)
except ValueError as err:
print(err) # Type names and field names cannot be a keyword: 'class' # 类成员字段参数名称重复 age
try:
p1 = namedtuple('Person','age,gender,name,age')
print(p1._fields)
except ValueError as err:
print(err)
# Encountered duplicate field name: 'age'

但是也有时候我们是无法控制的,如果参数的名称来自外部,比如是通过读取数据库中的内容来传递的参数,此时我们无法手工的修改参数名称,那该如何是好呢! 别担心,只需要增加一个属性就OK了,它就是 rename

# 参数字段的名称非法,包含系统名称class
try:
p = namedtuple('Person','age,name,class,gender',rename=True)
print(p._fields)
except ValueError as err:
print(err) # ('age', 'name', '_2', 'gender') # 类成员字段参数名称重复 age
try:
p1 = namedtuple('Person','age,gender,name,age',rename=True)
print(p1._fields)
except ValueError as err:
print(err)
# ('age', 'gender', 'name', '_3')

从以上的实例我们看出,当有参数错误的时候,系统自动将错误的参数通过增加 "下划线+参数索引" 的方式自动将参数名称替换了。

关于 namedtuple 的个人总结

# namedtuple 总结
from collections import namedtuple # 创建有两种方式:列表 or 有空格的字符串
Website = namedtuple('Website', ['name', 'url', 'founder'])
Website = namedtuple('Website', 'name url founder') # 赋值有两种方式:
# 1、可迭代对象,元组 or 列表 w = ('Sohu', 'http://www.google.com/', u'张朝阳')
l = ['Sina', 'http://www.sina.com.cn/', '王志东']
# 以元组形式赋值
w1 = Website._make(w)
Website(name='Sohu', url='http://www.google.com/', founder='张朝阳')
# 以列表形式赋值
w2 = Website._make(l)
Website(name='Sina', url='http://www.sina.com.cn/', founder='王志东') # 除了上边这样,我们还可以直接赋值(执行一个函数),但我总感觉是 类的实例化
w3 = Website(name='163', url='http://www.163.com/', founder='丁磊') (input)
Website(name='163', url='http://www.163.com/', founder='丁磊') (output) # 关于点 . 操作
# 我们可以通过 . 的方式获取数据 当然索引的方式也是可以的
eg:
print(w1.name, w1.url, w1.founder)
Sohu http://www.google.com/ 张朝阳 print(w1[0], w1[1], w1[2])
Sohu http://www.google.com/ 张朝阳
# 那这样 通过索引都能获取数据,我们可以尝试另一种方式
print('%s %s %s'%w1)
Sohu http://www.google.com/ 张朝阳 # 看到这里,我理解的是:其实这个方法(函数)实际上丢回的接口还是一个元组,只是有对应的枚举获取方式
# namedtuple子类不仅可以使用item的index访问item,还可以通过item的name进行访问。可以将namedtuple理解为c中的struct结构,其首先将各个item命名,
然后对每个item赋予数据。

python 之 Collections模块的更多相关文章

  1. Python中collections模块

    目录 Python中collections模块 Counter defaultdict OrderedDict namedtuple deque ChainMap Python中collections ...

  2. Python的collections模块中namedtuple结构使用示例

      namedtuple顾名思义,就是名字+元组的数据结构,下面就来看一下Python的collections模块中namedtuple结构使用示例 namedtuple 就是命名的 tuple,比较 ...

  3. python:collections模块

    Counter类 介绍:A counter tool is provided to support convenient and rapid tallies 构造:class collections. ...

  4. python之collections模块(OrderDict,defaultdict)

    前言: import collections print([name for name in dir(collections) if not name.startswith("_" ...

  5. 转载:Python中collections模块

    转载自:Python中collections模块 目录 Python中collections模块 Counter defaultdict OrderedDict namedtuple deque Ch ...

  6. python的Collections 模块

    Collections 模块 知识点 Counter 类 defaultdict 类 namedtuple 类 在这个实验我们会学习 Collections 模块.这个模块实现了一些很好的数据结构,它 ...

  7. Python中collections模块的使用

    本文将详细讲解collections模块中的所有类,和每个类中的方法,从源码和性能的角度剖析. 一个模块主要用来干嘛,有哪些类可以使用,看__init__.py就知道 '''This module i ...

  8. 【python】collections模块(有序字典,计数器,双向队列)

    collections模块基本介绍 我们都知道,Python拥有一些内置的数据类型,比如str, int, list, tuple, dict等, collections模块在这些内置数据类型的基础上 ...

  9. Python中Collections模块的Counter容器类使用教程

    1.collections模块 collections模块自Python 2.4版本开始被引入,包含了dict.set.list.tuple以外的一些特殊的容器类型,分别是: OrderedDict类 ...

随机推荐

  1. 使用DaoCloud持续构建docker镜像,自动化部署

    我们学会了在主机上安装部署docker,也学会了构建自己的docker镜像和容器,启停也都会用了,下一步就需要持续构建发布docker的技能了. 我们希望能在代码提交后,有个远程服务能自动开始构建项目 ...

  2. TeamTalk源码分析(十一) —— pc客户端源码分析

           --写在前面的话  在要不要写这篇文章的纠结中挣扎了好久,就我个人而已,我接触windows编程,已经六七个年头了,尤其是在我读研的三年内,基本心思都是花在学习和研究windows程序上 ...

  3. 正则 匹配 HTML 标签

    var tt=((result.data).toString()).match(/<style(([\s\S])*?)<\/style>/g);

  4. linux c++ 服务器端开发面试必看书籍

    摘自别人博客,地址:http://blog.csdn.net/qianggezhishen/article/details/45951095 打算从这开始一本一本开始看 题外话: 推荐一个 githu ...

  5. TOF 初探

    TOF 简介 TOF是Time of flight的简写,直译为飞行时间的意思.所谓飞行时间法3D成像,是通过给目标连续发送光脉冲,然后用传感器接收从物体返回的光,通过探测光脉冲的飞行(往返)时间来得 ...

  6. Markdown 效果测试

    欢迎使用 Cmd - 在线 Markdown 编辑阅读器 \[ \int e^{-x^2 - y^2} dx = \sqrt{2 \pi} \] 我们理解您需要更便捷更高效的工具记录思想,整理笔记.知 ...

  7. 通过拖拽prefab来存储相应的路径

    更新了一下,支持数组和嵌套数据结构. using UnityEngine; using System.Collections; using UnityEditor; using System.Refl ...

  8. 《DSP using MATLAB》示例Example6.29

    代码: % The following funciton computes the filter % coefficients shown in Table 6.2 b = firpm(30, [0, ...

  9. 使用反相器的rc振荡电路

    多谐振荡器是一种自激振荡电路,该电路在接通电源后无需外接触发信号就能产生一定频率和幅值的矩形脉冲波或方波.由于多谐振荡器在工作过程中不存在稳定状态,故又称为无稳态电路. 一.门电路组成的多谐振荡器 1 ...

  10. matlab 中的function定义. 用最简单的例子说明.

    function y=myfunction(a,b)其中a,b是输入函数的参数,y是函数返回的值.当需要返回多个值时,可以将y看作一个数组,或者直接将函数的开头写成如function [x,y]=my ...