python2.7的collections中提供了5种内置数据类型
python3.5中多提供了4种,红色字体的是多出来的
name | functions |
---|---|
namedtuple | factory function for creating tuple subclasses with named fields |
deque | list-like container with fast appends and pops on either end |
Counter | dict subclass for counting hashable objects |
OrderedDict | dict subclass that remembers the order entries were added |
defaultdict | dict subclass that calls a factory function to supply missing values |
UserDict | wrapper around dictionary objects for easier dict subclassing |
UserList | wrapper around list objects for easier list subclassing |
UserString | wrapper around string objects for easier string subclassing |
ChainMap | dict-like class for creating a single view of multiple mappings |
namedtuple
In [85]: Point = namedtuple('Point',['x','y'])
In [86]: p = Point(3,4)
In [87]: p.x
Out[87]: 3
In [88]: p[0]
Out[88]: 3
In [89]: p.__dict__
Out[89]: OrderedDict([('x', 3), ('y', 4)])
In [89]: p.__dict__
Out[89]: OrderedDict([('x', 3), ('y', 4)])
In [90]: p.__repr__
Out[90]: <bound method Point.__repr__ of Point(x=3, y=4)>
In [91]: p.__repr__()
Out[91]: 'Point(x=3, y=4)'
#_make生成一个新的实例对象
In [93]: a = [11,22]
In [94]: p._make(a)
Out[94]: Point(x=11, y=22)
In [100]: Point(*a)#字典也可以使用同样的方法
Out[100]: Point(x=11, y=22)
#作为一个字典
In [101]: p._asdict()
Out[101]: OrderedDict([('x', 3), ('y', 4)])
#replace替换
In [102]: p._replace(x=33)
Out[102]: Point(x=33, y=4)
deque
depue的操作较为类似
In [103]: d = deque(maxlen=10)#设定队列最大长度
In [104]: d.append('a')
In [105]: d
Out[105]: deque(['a'])
In [106]: d.appendleft('b')
In [107]: d
Out[107]: deque(['b', 'a'])
In [108]: d.extend('c')
In [109]: d
Out[109]: deque(['b', 'a', 'c'])
In [110]: d.extendleft('Z')
#如果加入d.extenfleft('QWER'),最后加的会出现在左边
In [119]: d.extendleft('QWER')
In [120]: d
Out[120]: deque(['R', 'E', 'W', 'Q', 'c', 'Z', 'b', 'a'])
In [111]: d
Out[111]: deque(['Z', 'b', 'a', 'c'])
In [112]: d.rotate(1)
In [113]: d
Out[113]: deque(['c', 'Z', 'b', 'a'])
In [114]: c=deque(['Z', 'b', 'a', 'c'])
In [115]: c.appendleft(c.pop())
In [116]: c
Out[116]: deque(['c', 'Z', 'b', 'a'])
Counter
Counter继承与dict,所以有dict的update,del,fromkeys等内置方法
#Counter可以接受字典类型,字符串,变量,字典,元组
In [8]: c = Counter({'a':1,'b':2})
In [11]: c = Counter(a=1,b=2)
In [13]: list(c.elements())
Out[13]: ['a', 'b', 'b']
In [4]: c = Counter('aabcdajflasdjfoeicnjafjejflaksjdf')
#c.most_common(n) 统计出现次数最多的n个元素
In [5]: c.most_common(3)
Out[5]: [('a', 6), ('j', 6), ('f', 5)]
#列出所有c的元素,是一个itertools.chain类型
In [6]: c.elements()
Out[6]: <itertools.chain at 0x42aceb8>
In [7]: list(c.elements())
Out[7]:
['a',
'a',
'a',
'a',
'a',
'a',
'c',
'c',
'b',
'e',
'e',
'd',
'd',
'd',
'f',
'f',
'f',
'f',
'f',
'i',
'k',
'j',
'j',
'j',
'j',
'j',
'j',
'l',
'l',
'o',
'n',
's',
's']
In [63]: c =Counter(a=4,b=2)
In [64]: c =Counter(a=4,b=2,c=0,d=-2)
In [65]: d = Counter(a=1,b=2)
#将key一样的进行相减,如果没有key,value默认是0,然后生成一个新的字典
In [66]: c.subtract(d)
In [67]: c
Out[67]: Counter({'a': 3, 'b': 0, 'c': 0, 'd': -2})
#可以进行加减与或(+,-,&,|)运算,只是对相同的key做操作
In [68]: c =Counter(a=4,b=2,c=0,d=-2)
In [69]: d = Counter(a=1,b=2)
In [70]: c-d
Out[70]: Counter({'a': 3})
In [71]: c+d
Out[71]: Counter({'a': 5, 'b': 4})
In [75]: c|d
Out[75]: Counter({'a': 4, 'b': 2})
In [76]: c&d
Out[76]: Counter({'a': 1, 'b': 2})
OrderedDict
a regular dict有序字典
In [130]: t = (('a',1),('b',2),('c',3))
In [131]: t
Out[131]: (('a', 1), ('b', 2), ('c', 3))
In [132]: a = dict(t)
In [133]: a
Out[133]: {'a': 1, 'b': 2, 'c': 3}
In [134]: b = OrderedDict(t)
In [135]: b
Out[135]: OrderedDict([('a', 1), ('b', 2), ('c', 3)])
In [136]: for k,v in a.iteritems():
...: print("key:{} value:{}".format(k,v))
...:
key:a value:1
key:c value:3
key:b value:2
In [137]: for k,v in b.iteritems():
...: print("key:{} value:{}".format(k,v))
...:
key:a value:1
key:b value:2
key:c value:3
defaultdict
可以将v设置成set,list,int等,你想使用的类型
如果设置为list,set类型就要使用append方法了
In [139]: a = "123123123345564566678"
In [143]: d = defaultdict(int)
In [144]: for i in a:
...: d[i] +=1
...:
In [145]: d
Out[145]:
defaultdict(int,
{'1': 3, '2': 3, '3': 4, '4': 2, '5': 3, '6': 4, '7': 1, '8': 1})
In [147]: s_list = [('student','john'),('student','lihua'),('teacher','wang'),('teacher','zhang')]
In [148]: d = defaultdict(list)
In [149]: for k,v in s_list:
...: d[k].append(v)
...:
In [150]: d
Out[150]: defaultdict(list, {'student': ['john', 'lihua'], 'teacher': ['wang', 'zhang']})
# 可以使用没有参数的回调函数
In :def zero():
... return 1
...
In :zero_dict = defaultdict(zero)
In :zero_dict['a']
Out:1
# 也可使用lamdba表达式
In :lambda_dict = defaultdict(lambda: 1)
In :lambda_dict['a']
Out:1
UserDict,UserList,UserString
用户自定义Dict,list,String属性,
直接地子类化类似dict或者list或者str这样的内建类型非常容易出错,因为大多数的内建方法会忽略用户所定义的重写方法。从被设计成易于扩展的collections模块的UserDict,UserList和UserString派生类,而不是子类化内建。
In [66]: class TestDict(dict):
...: def __getitem__(self,key):
...: return 99
...:
In [67]: t = TestDict(a='123')
In [68]: t
Out[68]: {'a': 99}
In [69]: d = {}
In [70]: d.update(t)
In [71]: d
Out[71]: {'a': '123'}
#UserDict不是继承Dict,是继承MutableMapping
In [72]: class NiceClass(UserDict):
...: def __getitem__(self,key):
...: return 100
...:
In [73]: n=NiceClass(a='123')
In [74]: n
Out[74]: {'a': '123'}
In [75]: n['a']
Out[75]: 100
In [76]: d = {}
In [77]: d.update(n)
In [78]: d['a']
Out[78]: 100
ChainMap
将多个字典放在一个chainmap中,运行效率会比update方法快很多,
In [7]: l1 = [1,2,3,4]
In [8]: l2=[5,6,7,8]
In [9]: l = ChainMap(l1,l2)
In [10]: l
Out[10]: ChainMap([1, 2, 3, 4], [5, 6, 7, 8])
In [12]: %timeit l=ChainMap(l1,l2)
The slowest run took 9.99 times longer than the fastest. This could mean that an intermediate result
is being cached.
1000000 loops, best of 3: 988 ns per loop
In [13]: %timeit l=l1.append(l2)
The slowest run took 32.75 times longer than the fastest. This could mean that an intermediate resul
t is being cached.
10000000 loops, best of 3: 145 ns per loop
In [51]: d1 = {'a':1,'b':2}
In [52]: d2 = {'c':3,'d':4}
In [53]: d = ChainMap(d1,d2)
In [54]: d.maps
Out[54]: [{'a': 1, 'b': 2}, {'c': 3, 'd': 4}]
In [59]: child_d = d.new_child()
In [60]: child_d['a']
Out[60]: 1
In [61]: child_d['a']=23
In [62]: child_d['a']
Out[62]: 23
In [64]: child_d.parents
Out[64]: ChainMap({'a': 1, 'b': 2}, {'d': 4, 'c': 3})
#使用new_child方法复制出来的对象,如果修改的话,不会修改父对象
想深入了解可以去看看源码
(于2016年12月31日,http://blog.csdn.net/bzd_111)