Collections模块
namedtuple
Python元组的升级版本 -- namedtuple(具名元组)
因为元组的局限性:不能为元组内部的数据进行命名,所以往往我们并不知道一个元组所要表达的意义,所以在这里引入了 collections.namedtuple 这个工厂函数,来构造一个带字段名的元组。具名元组的实例和普通元组消耗的内存一样多,因为字段名都被存在对应的类里面。这个类跟普通的对象实例比起来也要小一些,因为 Python 不会用 __dict__ 来存放这些实例的属性。
返回一个具名元组子类 typename,其中参数的意义如下:
- typename:元组名称
- field_names: 元组中元素的名称
- rename: 如果元素名称中含有 python 的关键字,则必须设置为 rename=True
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
from collections import namedtuple
User = namedtuple( "User" , [ "name" , "gender" , "age" ])
# 创建一个User对象
user = User(name = 'Runoob' , gender = 'male' , age = 12 )
# 获取所有字段名
print ( user._fields )
# 也可以通过一个list来创建一个User对象,这里注意需要使用"_make"方法
user = User._make([ 'Runoob' , 'male' , 12 ])
print ( user )
# User(name='user1', gender='male', age=12)
# 获取用户的属性
print ( user.name )
print ( user.gender )
print ( user.age )
# 修改对象属性,注意要使用"_replace"方法
user = user._replace(age = 22 )
print ( user )
# User(name='user1', gender='male', age=21)
# 将User对象转换成字典,注意要使用"_asdict"
print ( user._asdict() )
# OrderedDict([('name', 'Runoob'), ('gender', 'male'), ('age', 22)])
|
defaultdict
案例导入,统计字符串中每个字符出现的次数
01
02
03
04
05
06
07
08
09
10
11
|
<font color = "#262626" >a = "aabbccd"
ret = {}
for i in a:
if i not in ret:
ret[i] = 1
else :
ret[i] + = 1
print (ret)< / font>
|
1
2
3
4
5
6
|
<i><i><font color = "#262626" > from collections import defaultdict
ret = defaultdict( int )
for i in a:
ret[i] + = 1
print (ret)< / font>< / i>< / i>
|
使用defaultdict任何未定义的key都会默认返回一个根据method_factory参数不同的默认值, 而相同情况下dict()会返回KeyError.
1
2
3
4
|
<font color = "#262626" >d1 = dict ()
d2 = defaultdict( list )
print (d1[ 'a' ])
print (d2[ 'a' ])< / font>
|
default_factory 接收一个工厂函数作为参数, 例如int str list set等.
defaultdict在dict的基础上添加了一个__missing__(key)方法, 在调用一个不存的key的时候, defaultdict会调用__missing__, 返回一个根据default_factory参数的默认值, 所以不会返回Keyerror.
deque
deque和list的区别:
- deque是线程安全的,list不是
- deque来说从队列两端添加或弹出元素的复杂度都是O(1)。而从列表的头部插入或移除元素时,列表的复杂度为O(N),在实现队列时,deque比list更适合。deque是一个双向链表,所以操作头尾非常简单。随机往中间插入数据,deque与list的时间复杂度都是O(n), 根据index读list,时间复杂度为O(1),deque是O(n)
python的queue就是基于deque实现的
deque中的特有的方法
01
02
03
04
05
06
07
08
09
10
11
|
<font color = "#262626" > from collections import namedtuple, deque
b_deque = deque([ 1 , 231 , 45 , 641 ])
b_deque.appendleft( 0 )
b_deque.extendleft([ 5 , 6 , 7 ])
print (b_deque.popleft())
print (b_deque)
# 限制deque的长度
c_deque = deque([ 1 , 2 , 3 , 4 ], maxlen = 4 )
c_deque.append( 5 ) # 此时会在末尾加入5,同时删除最前面的1。</font>
|
Counter(计数器)
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
a = Counter( "sdfdsgfdgfj" )
print (a)
print ( list (a.elements()))
# 列出前n个元素
print (a.most_common( 2 ))
print (a.items())
# 增加元素
b = Counter([ 11 , 22 ])
print (b)
b.update([ 11 , 22 ])
print (b)
# 减去元素
b.subtract([ 11 ])
print (b)
|
OrderedDict(有序字典)
Python3.6之后默认的字典就是有序字典,但是OrderedDict有几个好用的方法是普通字典没有的
1
2
3
4
5
6
7
8
9
|
<font color = "#262626" >dic = OrderedDict()[ / color][ / p]
dic[ "b" ] = 456
dic[ "c" ] = 123
dic[ "a" ] = 789
print (dic)
dic.move_to_end( "c" )
print (dic)
print (dic.popitem())
print (dic)< / font>
|
ChainMap
我们有多个字典或者映射,想把它们合并成为一个单独的映射,有人说可以用update进行合并,这样做的问题就是新建了一个数据结构以致于当我们对原来的字典进行更改的时候不会同步。如果想建立一个同步的查询方法,可以使用ChainMap
ChainMap最基本的使用,可以用来合并两个或者更多个字典,当查询的时候,从前往后依次查询。
有一个注意点就是当对ChainMap进行修改的时候总是只会对第一个字典进行修改
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
a = { "a" : 123 , "b" : 456 }
# b = {"a": 789, "b": 101}
b = { "c" : 123 , "d" : 456 }
chain_map = ChainMap(a, b)
# for k, v in chain_map.items():
# print(k, v)
# new_child 在开头创建一个新的空字典
c = chain_map.new_child()
c[ "m" ] = 000
print (c)
# parents去掉第一个字典
print (c.parents)
for k, v in chain_map.items():
print (k, v)
|