Python 的 collections是一个内建模块,提供了很多集合类。
namedtuple
我们知道tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成:
=(1,2)
但是,看到(1, 2),很难看出这个tuple是用来表示一个坐标的。
定义一个class又小题大做了,这时,namedtuple就派上了用场:
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(1, 2)
p.x
>>>1
p.y
>>>2
namedtuple是一个自定义tuple对象,并规定来tuple元素个数,并可以用属性来索引tuple某个元素。
deque
list存储数据,按索引访问元素很快,但插入和删除元素很慢。
deque是为了高效实现插入和删除的双向列表,适合于队列和栈:
from collections import deque
q = deque(['a','b','c'])
q.append('x')
q.appendleft('y')
>>>q
deque(['x','a','b','c','x'])
deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效地往头部添加或删除元素。
defaultdict
使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict:
from collections import defaultdict
dd =defaultdict(lambda:'N/A')
dd['key1'] ='abc'
dd['key1']
>>>'abc'
dd['key2']
>>>'N/A'
注意默认值是调用函数返回的,而函数在创建defaultdict对象时传入。
除了在Key不存在时返回默认值,defaultdict的其他行为跟dict是完全一样的。
OrderedDict
使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。如果要保持Key的顺序,可以用OrderedDict:
>>> 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']
OrderedDict可以实现一个FIFO(先进先出)的dict,当容量超出限制时,先删除最早添加的Key:
class LastUpdateOrderedDict(OrderedDict):
def __init__(self,capacity):
super(LastUpdateOrderedDict,self).__init__()
self._capacity =capacity
def __setitem__(self,key,value):
containsKey =1 if key in self else 0
if len(self) - containsKey>= self._capacity:
last = self.popitem(last=False)
print 'remove:', last
if containsKey:
del self[key]
print 'set:',(key,value)
else:
print 'add:',(key,value)
OrderedDict.__setitem__(self,key,value)
Counter
Counter是一个简单的计数器,例如,统计字符出现的个数:
rom collections import Counter
c = Counter()
for ch in 'programming':
c[ch] = c[ch]+1
>>> c
Counter({'g': 2, 'm': 2, 'r': 2, 'a': 1, 'i': 1, 'o': 1, 'n': 1, 'p': 1})