python collections中的数据结构

OrderedDict

字典是无序的,有序字典能够使字典保持有序。不过OrderedDict使用一个双向链表实现,增加了内存开销。使用sys.getsizeof()查看内存使用情况,可以看出有序字典开销较大。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from collections import OrderedDict
import sys

dict1 = {
'name': 'wang',
'age': 22
}

dict2 = OrderedDict()
dict2['name'] = 'wang'
dict2['age'] = 22

print(dict1, sys.getsizeof(dict1)) # {'age': 22, 'name': 'wang'} 288
print(dict2, sys.getsizeof(dict2)) # OrderedDict([('name', 'wang'), ('age', 22)]) 928

defaultdict

构建一键多值字典。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from collections import defaultdict

d = defaultdict(list)
d['a'].append('ab')
d['a'].append('acd')
d['a'].append('bef')

print(d)

s = defaultdict(set)
s['a'].add('ab')
s['a'].add('ab')
s['b'].add('b')

print(s)

Counter

统计每个元素出现的次数,也有类似排行榜的功能,如取出现次数最多的三个元素。

1
2
3
4
5
6
from collections import Counter

c = Counter('python cookbook')

print(c) # Counter({'o': 5, 'k': 2, 'p': 1, 't': 1, 'h': 1, 'y': 1, 'c': 1, 'b': 1, 'n': 1, ' ': 1})
print(c.most_common(2)) # [('o', 5), ('k', 2)]

ChainMap

使用ChainMap可以将多个字典联合起来。使用update也可以合并字典,不过合并后的字典不与以前的字典发生联系,且只能合并两个。显然,ChainMap显得比较灵活。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from collections import ChainMap

dict1 = {
'a': 3,
'b': 4
}

dict2 = {
'b': 5,
'c': 6
}

dict3 = ChainMap(dict1, dict2)
print(dict3['b'])

dict4 = dict(dict1, **dict2)
print(dict4['b'])

namedtuple

命名元组能够让元组以属性的形式访问,增加可读性。另外注意,元组是以,区分,而非()_asdict使命名元组转化为有序字典。

1
2
3
4
5
6
7
8
9
10
from collections import namedtuple

Host = namedtuple('Host', ['hostname', 'port'])
h = Host('127.0.0.1', 3000)

print(h.hostname) # 127.0.0.1
print(h.port) # 3000

# _asdict使命名元组转化为有序字典
print(h._asdict()) # OrderedDict([('hostname', '127.0.0.1'), ('port', 3000)])