python标准库学习(一)

collections

该模块实现专门的容器数据类型,提供Python通用内置容器(dict,set,list,tuple)的替代方案。

nametuple() 工厂函数用于创建带有命名字段的元组子类
deque() 列表式容器,在两端有快速附加和弹出
ChainMap() 类似于类的类,用于创建多个映射的单个视图
Counter () dict子类用于计算hashable对象
OrderedDict () dict子类,记住已添加的条目的顺序
defaultdict () dict子类调用一个工厂函数时提供缺失值
UserDict () 包装字典对象,更容易dict子类化
UserList () 包装列表对象以方便列表子类化
UserString() 包装字符串对象,更容易字符串子类化

ChainMap

ChainMap用来将多个dict(字典)组成一个list(只是比喻),可以理解成合并多个字典,但和update不同,而且效率更高。

ChainMap用来将多个dict组成一个list之后,多个dict之间的键不冲突。当多个dict有重复键时,使用get方法:如chainMap.get('name')将会返回第一个dict[‘name’]。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 新建ChainMap及它的结构
In[2]: from collections import ChainMap
In[3]: m1 = {'color': 'red', 'user': 'guest'}
In[4]: m2 = {'name': 'drfish', 'age': '18'}
In[5]: chainMap = ChainMap(m1, m2)
In[6]: print(chainMap.items())
ItemsView(ChainMap({'color': 'red', 'user': 'guest'}, {'name': 'drfish', 'age': '18'}))

# 获取ChainMap中的元素
In[7]: print(chainMap.get('name'))
drfish
In[8]: print(chainMap.get('not'))
None

# 新增map
In[9]: m3 = {'name': 'boy'}
In[10]: chainMap = chainMap.new_child(m3)
In[11]: print(chainMap.items())
ItemsView(ChainMap({'name': 'boy'}, {'color': 'red', 'user': 'guest'}, {'name': 'drfish', 'age': '18'}))
In[12]: print(chainMap.get('name'))
'boy'

#一次遍历多个字典
In[13]: for i in chainMap.maps:
print("----------------")
for mykey in i.keys():
print(mykey,i[mykey])

----------------
name boy
----------------
color red
user guest
----------------
name drfish
age 18

Counter

Counter是一个简单的计数器,使用起来非常方便。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
>>> from collections import Counter
>>> c = Counter(a=4, b=2, c=0, d=-2) #不大于0的全部忽略
>>> sorted(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']

>>> Counter('abracadabra').most_common(3) #返回出现次数最多的字符
[('a', 5), ('r', 2), ('b', 2)]

>>> cnt = Counter() # 统计列表中元素出现的个数
>>> for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:
... cnt[word] += 1
...
>>> cnt
Counter({'blue': 3, 'red': 2, 'green': 1})

>>> cnt = Counter() # 统计字符串中元素出现的个数
>>> for ch in 'hello':
... cnt[ch] = cnt[ch] + 1
...
>>> cnt
Counter({'l': 2, 'o': 1, 'h': 1, 'e': 1})

deque

deque就是一个双端队列,与list非常相似,不过可以同时在list的左边增删元素,支持线程安全 ,从队列两端添加或弹出元素的复杂度都是O(1),而从列表的头部插入或移除元素时,列表的复杂度为O(N)。 deque和list从中部处理数据复杂度都为为O(N)。

1
2
3
4
5
6
7
8
9
10
11
12
In[72]: dq = deque('abc')
In[73]: dq
Out[73]: deque(['a', 'b', 'c'])
In[74]: dq.append('A')
In[75]: dq.appendleft('Z')
In[76]: dq
Out[76]: deque(['Z', 'a', 'b', 'd', 'A'])
In[77]: dq.popleft()
Out[77]: 'Z'
In[78]: dq.extendleft("hello")
In[79]: dq
Out[79]: deque(['o', 'l', 'l', 'e', 'h', 'a', 'b', 'c', 'A'])

defaultdict

使用 list 作为 default_factory,很容易将键值对的序列分组到列表的字典,类似setdefault

当第一次遇到每个键时,它不在映射中;因此使用返回空 listdefault_factory 函数自动创建一个条目。然后,list.append() 操作将值附加到新列表。当再次遇到键时,查找继续正常(返回该键的列表),list.append() 操作将另一个值添加到列表。这种技术比使用 dict.setdefault() 的等效技术更简单和更快

1
2
3
4
5
6
7
8
>>> from collections import defaultdict
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
... d[k].append(v)
...
>>> sorted(d.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
1
2
3
4
5
6
7
>>> d = {}
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> for k, v in s:
... d.setdefault(k,[]).append(v)
...
>>> sorted(d.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

default_factory 设置为int 使 defaultdict 可用于计数,当首次遇到字母时,映射中缺少字母,因此 default_factory 函数调用 int() 以提供默认计数为零。增量操作然后建立每个字母的计数。

1
2
3
4
5
6
7
>>> s = 'mississippi'
>>> d = defaultdict(int)
>>> for k in s:
... d[k] += 1
...
>>> sorted(d.items())
[('i', 4), ('m', 1), ('p', 2), ('s', 4)]

default_factory 设置为 set使得 defaultdict 可用于构建集合的字典

1
2
3
4
5
6
7
>>> s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]
>>> d = defaultdict(set)
>>> for k, v in s:
... d[k].add(v)
...
>>> sorted(d.items())
[('blue', {2, 4}), ('red', {1, 3})]

OrderedDict

有序字典与常规字典类似,但它们记住项目插入的顺序。在对有序字典进行迭代时,项目按它们的键首次添加的顺序返回。