Python附带⼀个模块,它包含许多容器数据类型,名字叫作collections模块
我们将讨论的是:
counter ,dict的子类,计算可hash的对象;
defaultdict ,dict的子类,可以调用提供默认值的函数
deque ,类似于list的容器,可以快速的在队列头部和尾部添加、删除元素;
namedtuple
enum.Enum (包含在Python 3.4以上)
Counter
collections模块中有一个类Counter,可以支持方便、快速的计数。通过查看源码可以知道
Counter类继承自dict。
调用时可不传值,或者传入一个可迭代对象,字典,关键字参数。
Counter对象可以使用dict转换成常规的dict。
from collections import *
a='abhbachsks'
cnt=Counter(a) #从可迭代的字符串初始化counter
print(cnt)
print(type(cnt))
print(dict(cnt))
#打印
Counter({'a': 2, 'b': 2, 'h': 2, 's': 2, 'c': 1, 'k': 1})
<class 'collections.Counter'>
{'a': 2, 'b': 2, 'h': 2, 'c': 1, 's': 2, 'k': 1}
使用dir函数查看cnt是可以看到,cnt不仅具有与字典一样的方法,还新增了Counter自己的一些功能(如:elements(),most_common(),subtract())。
print(dir(cnt))
#打印
['__add__', '__and__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dict__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__',
'__iadd__', '__iand__', '__init__', '__init_subclass__', '__ior__', '__isub__', '__iter__', '__le__',
'__len__', '__lt__', '__missing__', '__module__', '__ne__', '__neg__', '__new__', '__or__', '__pos__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__sub__',
'__subclasshook__', '__weakref__', '_keep_positive', 'clear', 'copy', 'elements', 'fromkeys', 'get', 'items',
'keys', 'most_common', 'pop', 'popitem', 'setdefault', 'subtract', 'update', 'values']
#部分字典方法
print(cnt.get('a'))
print(cnt.keys())
print(cnt.items())
>>2
>>dict_keys(['a', 'b', 'h', 'c', 's', 'k'])
>>dict_items([('a', 2), ('b', 2), ('h', 2), ('c', 1), ('s', 2), ('k', 1)])
Counter对象类似于字典,如果某个项缺失,不会报出KeyError,会返回0或者None。
from collections import *
a='abhbachsks'
cnt=Counter(a)
print(cnt.get('o'))
print(cnt['p'])
>>None
>>0
将一个元素的数目设置为0,并不能将它从counter中删除,使用del可以将这个元素删除。
del cnt['b']
print(cnt)
>>Counter({'a': 2, 'h': 2, 's': 2, 'c': 1, 'k': 1})
element():
返回一个迭代器,需要使用list转换成list,或者set集合转换使用,每个元素重复的次数为它的数目,顺序是任意的顺序,如果一个元素的数目少于1,那么elements()就会忽略它,Counter使用element()后,
注:无法使用str或dict转换
d={'e':0,'f':2,'g':1,'d':4}
cnt=Counter(d)
print(cnt.elements())
print(list(cnt.elements()))
print(set(cnt.elements())) #出来的值是无序的
>> <itertools.chain object at 0x03382190>
>> ['f', 'f', 'g', 'd', 'd', 'd', 'd']
>> {'f', 'g', 'd'}
most_common():
返回一个列表,列表元素是一对对的元组,传入参数n,则返回counter中n个最大数目的元素,如果不填或者为None,most_common()将会返回counter中的所有元素
d={'e':0,'f':2,'g':1,'d':4,'a':2}
cnt=Counter(d)
print(cnt.most_common())
print(cnt.most_common(2))
>>[('d', 4), ('f', 2), ('a', 2), ('g', 1), ('e', 0)]
>>[('d', 4), ('f', 2)]
subtract():
没有返回值,使用subtract的对象自己直接被修改,从一个可迭代对象中或者另一个映射(或counter)中,元素相减,类似于dict.update(),但是subtracts 数目湘减而不是替换它们,输入和输出都有可能为0或者为负。
str1='abhbachsks'
dict1={'e':0,'f':2,'g':1,'d':4,'a':2}
cnta=Counter(str1)
print(cnta.subtract(dict1)) #cnta直接被修改,没有返回
print(cnta)
>>None
>>Counter({'b': 2, 'h': 2, 's': 2, 'c': 1, 'k': 1, 'a': 0, 'e': 0, 'g': -1, 'f': -2, 'd': -4})
#str1中没有"f",dict1中有"f",相减会出来负数
update():
没有返回值,使用update的对象自己直接被修改,从一个可迭代对象中或者另一个映射(或counter)中所有元素相加,类似于dict.upodate,是数目相加而非替换它们,另外,可迭代对象是一个元素序列,而非(key,value)对构成的序列;
str1='abhbachsks'
dict1={'e':0,'f':2,'g':1,'d':4,'a':2}
cnta=Counter(str1)
print(cnta.update(dict1)) #cnta直接被修改
print(cnta)
>>None
>>Counter({'a': 4, 'd': 4, 'b': 2, 'h': 2, 's': 2, 'f': 2, 'c': 1, 'k': 1, 'g': 1, 'e': 0})
在Counter对象进行数学操作,得多集合(counter中元素数目大于0)加法和减法操作,相加或者相减对应元素的数目;
交集返回对应数目的最小值;并集返回对应数目的最大值
每个操作均接受有符号的数目,但是输出并不包含数目为0或者为负的元素;
a = Counter(a=3,b=0,c=-2)
b = Counter(a=1,b=2,c=6)
print(a-b) #相减
print(a+b) #相加
print(a|b) #求并集
print(a&b) #求交集
>>
Counter({'a': 2})
Counter({'a': 4, 'c': 4, 'b': 2})
Counter({'c': 6, 'a': 3, 'b': 2})
Counter({'a': 1})
deque
类似于list的容器,可以快速的在队列头部和尾部添加、删除元素;
deque是栈和队列的一种广义实现,deque是"double-end queue"的简称;deque支持线程安全、有效内存地以近似O(1)的性能在deque的两端插入和删除元素,尽管list也支持相似的操作,但是它主要在固定长度操作上的优化,从而在pop(0)和insert(0,v)(会改变数据的位置和大小)上有O(n)的时间复杂度。
from collections import deque
de=deque('dsadsadcdh')
print(de)
de.append('u')
de.appendleft('0')
print(type(de))
print(list(de))
>> deque(['d', 's', 'a', 'd', 's', 'a', 'd', 'c', 'd', 'h'])
>> <class 'collections.deque'>
>> ['0', 'd', 's', 'a', 'd', 's', 'a', 'd', 'c', 'd', 'h', 'u']
deque可将可迭代对象转换成列表形式,可以使用list转化成常规list
具有一般list的特性,不仅可使用list常用方法,还可以使用其他独有的方法如:
1,append(x), 将x添加到deque的右侧;appendleft(x), 将x添加到deque的左侧;
from collections import deque
a=deque('dsdh')
a.append('abc')
a.appendleft('abc')
print(list(a))
>> ['abc', 'd', 's', 'd', 'h', 'abc']
2,extend(iterable), 将可迭代变量iterable中的元素添加至deque的右侧;extendleft(iterable), 将变量iterable中的元素添加至deque的左侧,往左侧添加序列的顺序与可迭代变量iterable中的元素相反;
from collections import deque
a=deque('dsdh')
a.extend('abc')
a.extendleft('abc')
print(list(a))
>> ['c', 'b', 'a', 'd', 's', 'd', 'h', 'a', 'b', 'c']
#左侧是‘abc’的反序‘cba’,右侧还是‘abc’顺序
3,pop(), 移除和返回deque中最右侧的元素,如果没有元素,将会报出IndexError;
popleft(), 移除和返回deque中最左侧的元素,如果没有元素,将会报出IndexError;
from collections import deque
a=deque('dsdho')
a.pop()
a.popleft()
print(list(a))
>>['s', 'd', 'h']
defaultdict
dict的子类,可以调用提供默认值的函数
defaultdict是内置数据类型dict的一个子类,基本功能与dict一样,只是重写了一个方法missing(key)和增加了一个可写的对象变量default_factory。
查看源码可知defaultdict类是继承了dict
待更新。。。。