流畅的python之collections模块
collections 模块提供了python 常用的数据结构以外的其他数据结构,分为以下几种
- namedtuple(): 特殊tuple子类,可以用名字和下标来访问
- deque: 双端队列,可以快速的从另外一侧追加和推出对象
- Counter: 计数器,主要用来计数
- OrderedDict: 有序字典
- defaultdict: 带有默认值的字典
- ChainMap:类似字典的容器类,将多个映射集合到一个视图里面
namedtuple 顾名思义,就是带名字的元组,有类似字典的访问方法,通过yourtuple.key来访问如下
#!/usr/bin/python3 # -*- coding: utf-8 -*- from collections import namedtuple persons = [ ('男', '1988-04-11', '张三'), ('女', '1993-03-26', '李四'), ('男', '1990-06-02', '王五') ] Person = namedtuple('person', ['sex', 'birthday', 'name']) # Person = namedtuple('person', ('sex', 'birthday', 'name')) # Person = namedtuple('person', 'sex, birthday, name') # Person = namedtuple('person', 'sex birthday name') if __name__ == '__main__': for person in persons: person = Person._make(person) # 可以通过_make(tuple类型) 或者 调用new方法创建 # person = Person(person[0], person[1], person[2]) print(person) print(person.name, person[0])
output:
person(sex='男', birthday='1988-04-11', name='张三') 张三 男 person(sex='女', birthday='1993-03-26', name='李四') 李四 女 person(sex='男', birthday='1990-06-02', name='王五') 王五 男
注:namedtuple(parm1, parm2)
parm1 为构造器的名字,parm2 可以是列表,元组,或者字符串
parm2 参数的元素个数需要和传入的参数个数一致,如: Person('男', '1988-04-11', '张三', '1383333333') 则会报错 Expected 3 arguments, got 4
deque
collections.deque
返回一个新的双向队列对象,方便对队列两端的操作 ,支持线程安全,对于从两端添加(append)或者弹出(pop),复杂度O(1)。
虽然list
对象也支持类似操作,复杂组O(n) 随着list长度增加消耗越大
如果 maxlen默认为 None ,可以增长到任意长度。否则,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。
from collections import deque d = deque(maxlen=10) print(d) d.extend('hello world') [i.upper() for i in d] ['P', 'Y', 'T', 'H', 'O', 'N'] d.append('e') d.appendleft('f') print(d)
output:
deque([], maxlen=10)
deque(['f', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'], maxlen=10)
Counter
Counter是一个dict子类,主要是用来对你访问的对象的频率进行计数。
常用方法:
- elements():返回一个迭代器,每个元素重复计算的个数,如果一个元素的计数小于1,就会被忽略。
- most_common([n]):返回一个列表,提供n个访问频率最高的元素和计数ChainMap
- subtract([iterable-or-mapping]):从迭代对象中减去元素,输入输出可以是0或者负数
- update([iterable-or-mapping]):从迭代对象计数元素或者从另一个 映射对象 (或计数器) 添加。
import collections print(collections.Counter('hello world')) # 统计单词数 print(collections.Counter('hello world hello world hello nihao'.split()))
output:
Counter({'l': 3, 'o': 2, 'r': 1, 'w': 1, 'h': 1, 'd': 1, 'e': 1, ' ': 1})
Counter({'hello': 3, 'world': 2, 'nihao': 1})
OrderedDict
Python字典中的键的顺序无序的,不受添加的顺序的控制。
collections.OrderedDict
保留他们添加顺序的字典对象。
from collections import OrderedDict demo_dict = {"a": 1, "b": 2, "c": 3} order_dict = OrderedDict(demo_dict) print (demo_dict, order_dict) demo_dict['s'] = 5 print (demo_dict) order_dict['s'] = 5 print(order_dict)
output:
{'b': 2, 'a': 1, 'c': 3} OrderedDict([('b', 2), ('a', 1), ('c', 3)])
{'s': 5, 'b': 2, 'a': 1, 'c': 3}
OrderedDict([('b', 2), ('a', 1), ('c', 3), ('s', 5)])
defaultdict
defaultdict(factory)
为字典的没有的key提供一个默认的值。参数应该是一个函数,当没有参数调用时返回默认值。如果没有传递任何内容,则默认为None
from collections import defaultdict demo_dict = {} try: print(demo_dict['s']) # KeyError except: pass default_dict = defaultdict(str) default_dict['s'] print(demo_dict) print(default_dict)
output:
{}
defaultdict(, {'s': ''})
ChainMap
一个 ChainMap 相当于多个字典求和。
from collections import ChainMap d1 = {"a": 1, "b": 2, "aa": 1} d2 = {"aa": 11, "bb": 22, "b": 3} sd = ChainMap(d1, d2) print(sd) for k, v in sd.items(): print(k, v)
output:
ChainMap({'aa': 1, 'a': 1, 'b': 2}, {'b': 3, 'bb': 22, 'aa': 11})
2 1
a 1
b 2
bb 22
aa 1
注:相同的key 值,前面覆盖后面的。
参考:作者:OneMore
出处:https://www.cnblogs.com/dianel/
原文2: http://www.zlovezl.cn/articles/collections-in-python/