collections
namedtuple
tuple
不可变,可迭代
拆包:
| x, y, z = ('a', 1, False)
print(x, y, z)
"""
a 1 False
"""
|
| x, *other = ('a', 1, False)
print(x, other)
"""
a [1, False]
"""
|
| my_tuple = ('a', [1, False])
my_tuple[1].append(2)
print(my_tuple)
"""
('a', [1, False, 2])
"""
|
一般不建议将可变对象放到 tuple 中
tuple优势:
- 性能优化
- 线程安全(因为是不可变对象)
- 可作为 dict 的 key(也是因为不可变,可哈希)
- 拆包特性
namedtuple
| namedtuple(
typename,
field_names,
*,
rename=False,
defaults=None,
module=None,
)
|
namedtuple 主要用于构建只有少数属性但是没有方法的对象,比如数据库条目
| from collections import namedtuple
User = namedtuple('User', ['name', 'age', 'height'])
user = User(name='cai', age=666, height=666)
print(user.age, user.name, user.height)
"""
666 cai 666
"""
|
| from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(1, 2)
print(p, p.x, p.y)
"""
Point(x=1, y=2) 1 2
"""
|
nametuple 是 tuple 的子类,占用内存和执行效率比定义简单的类要好
| from collections import namedtuple
User = namedtuple('User', ['name', 'age', 'height', "edu"])
user_tuple = ('cai', 666, 2333)
user = User(*user_tuple, "lalala")
print(user.age, user.name, user.height, user.edu)
"""
666 cai 2333 lalala
"""
|
1
2
3
4
5
6
7
8
9
10
11
12 | from collections import namedtuple
User = namedtuple('User', ['name', 'age', 'height', "edu"])
user_dict = {
"name": 'cai',
'age': 666,
'height': 2333
}
user = User(**user_dict, edu="lalala")
print(user.age, user.name, user.height, user.edu)
"""
666 cai 2333 lalala
"""
|
_make(iterable)
类方法从存在的序列或迭代实例创建一个新实例。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | from collections import namedtuple
User = namedtuple('User', ['name', 'age', 'height', "edu"])
user_tuple = ('cai', 666, 2333, "lalala")
user=User._make(user_tuple)
print(user.age, user.name, user.height, user.edu)
user_list = ['cai', 666, 2333, "lalala"]
user=User._make(user_list)
print(user.age, user.name, user.height, user.edu)
user_dict = {
"name": 'cai',
'age': 666,
'height': 2333,
'edu': 'lalal'
}
user=User._make(user_dict)
print(user.age, user.name, user.height, user.edu)
"""
666 cai 2333 lalala
666 cai 2333 lalala
age name height edu
"""
|
somenamedtuple._asdict()
返回一个新的 dict ,它将字段名称映射到它们对应的值
| from collections import namedtuple
User = namedtuple('User', ['name', 'age', 'height', "edu"])
user_tuple = ('cai', 666, 2333, "lalala")
user=User._make(user_tuple)
print(user._asdict())
"""
OrderedDict([('name', 'cai'), ('age', 666), ('height', 2333), ('edu', 'lalala')])
"""
|
拆包
| from collections import namedtuple
User = namedtuple('User', ['name', 'age', 'height', "edu"])
user_tuple = ('cai', 666, 2333, "lalala")
user=User._make(user_tuple)
name, age, *other = user
print(name, age, other)
"""
cai 666 [2333, 'lalala']
"""
|
defaultdict
| users = ["a", 'b', 'c', 'a']
user_dict = {}
for user in users:
user_dict.setdefault(user, 0)
user_dict[user] += 1
print(user_dict)
"""
{'a': 2, 'b': 1, 'c': 1}
"""
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | from collections import defaultdict
ddict = defaultdict(list)
print(ddict['cai'])
ddict = defaultdict(int)
print(ddict['cai'])
users = ['a', 'b', 'b', 'd']
for user in users:
ddict[user] += 1
print(ddict)
"""
[]
0
defaultdict(<class 'int'>, {'cai': 0, 'a': 1, 'b': 2, 'd': 1})
"""
|
1
2
3
4
5
6
7
8
9
10
11
12
13 | from collections import defaultdict
def gen_default():
return {
"name": 'cai',
'nums': 0
}
ddict = defaultdict(gen_default)
print(ddict['lalal'])
"""
{'name': 'cai', 'nums': 0}
"""
|
| from collections import defaultdict
ddict = defaultdict(lambda: None)
print(ddict['lalal'])
"""
None
"""
|
deque GIL 是线程安全的,list 不是线程安全的
Counter
字典的子类,提供了可哈希对象的计数功能
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
37
38 | >>> c = Counter('abcdeabcdabcaba') # count elements from a string
>>> c.most_common(3) # three most common elements
[('a', 5), ('b', 4), ('c', 3)]
>>> sorted(c) # list all unique elements
['a', 'b', 'c', 'd', 'e']
>>> ''.join(sorted(c.elements())) # list elements with repetitions
'aaaaabbbbcccdde'
>>> sum(c.values()) # total of all counts
15
>>> c['a'] # count of letter 'a'
5
>>> for elem in 'shazam': # update counts from an iterable
... c[elem] += 1 # by adding 1 to each element's count
>>> c['a'] # now there are seven 'a'
7
>>> del c['b'] # remove all 'b'
>>> c['b'] # now there are zero 'b'
0
>>> d = Counter('simsalabim') # make another counter
>>> c.update(d) # add in the second counter
>>> c['a'] # now there are nine 'a'
9
>>> c.clear() # empty the counter
>>> c
Counter()
>>> c = Counter('aaabbc')
>>> c['b'] -= 2 # reduce the count of 'b' by two
>>> c.most_common() # 'b' is still in, but its count is zero
[('a', 3), ('c', 1), ('b', 0)]
>>> c = Counter() # a new, empty counter
>>> c = Counter('gallahad') # a new counter from an iterable
>>> c = Counter({'a': 4, 'b': 2}) # a new counter from a mapping
>>> c = Counter(a=4, b=2) # a new counter from keyword args
|
OrderedDict
字典的子类,保存了他们被添加的顺序
| from collections import OrderedDict
user_dict = OrderedDict()
user_dict['b'] = 'b'
user_dict['a'] = 'a'
user_dict['c'] = 'c'
print(user_dict)
"""
OrderedDict([('b', 'b'), ('a', 'a'), ('c', 'c')])
"""
|
popitem(last=True)
有序字典的 popitem() 方法移除并返回一个 (key, value) 键值对。 如果 last 值为真,则按 LIFO 后进先出的顺序返回键值对,否则就按 FIFO 先进先出的顺序返回键值对。
| from collections import OrderedDict
user_dict = OrderedDict()
user_dict['b'] = 'b'
user_dict['a'] = 'a'
user_dict['c'] = 'c'
user_dict.popitem()
print(user_dict)
"""
OrderedDict([('b', 'b'), ('a', 'a')])
"""
|
move_to_end(key, last=True)
将现有 key 移动到有序字典的任一端。 如果 last 为真值(默认)则将元素移至末尾;如果 last 为假值则将元素移至开头。如果 key 不存在则会触发 KeyError:
| from collections import OrderedDict
user_dict = OrderedDict()
user_dict['b'] = 'b'
user_dict['a'] = 'a'
user_dict['c'] = 'c'
user_dict.move_to_end('b')
print(user_dict)
"""
OrderedDict([('a', 'a'), ('c', 'c'), ('b', 'b')])
"""
|
底层实现为循环双端链表
ChainMap
| from collections import ChainMap
user_dict1 = {'a': 'a', 'b': 'b'}
user_dict2 = {'c': '1', 'd': 2}
new_dict = ChainMap(user_dict1, user_dict2)
print(new_dict)
print(new_dict['c'])
"""
ChainMap({'a': 'a', 'b': 'b'}, {'c': '1', 'd': 2})
1
"""
|
| from collections import ChainMap
user_dict1 = {'a': 'a', 'b': 'b'}
user_dict2 = {'b': '1', 'd': 2}
new_dict = ChainMap(user_dict1, user_dict2)
print(new_dict)
print(new_dict['b'])
"""
ChainMap({'a': 'a', 'b': 'b'}, {'b': '1', 'd': 2})
b
"""
|
1
2
3
4
5
6
7
8
9
10
11
12 | from collections import ChainMap
user_dict1 = {'a': 'a', 'b': 'b'}
user_dict2 = {'b': '1', 'd': 2}
new_dict = ChainMap(user_dict1, user_dict2)
print(new_dict.maps)
new_dict.maps[0]['a'] = 'hhhh'
print(new_dict)
"""
[{'a': 'a', 'b': 'b'}, {'b': '1', 'd': 2}]
ChainMap({'a': 'hhhh', 'b': 'b'}, {'b': '1', 'd': 2})
"""
|
deque
deque([iterable[, maxlen]])
append(x)
: 添加 x 到右端。
appendleft(x)
: 添加 x 到左端。
clear()
: 移除所有元素,使其长度为0.
copy()
: 创建一份浅拷贝
count(x)
: 计算deque中个数等于 x 的元素
extend(iterable)
: 扩展deque的右侧,通过添加iterable参数中的元素
extendleft(iterable)
: 扩展deque的左侧,通过添加iterable参数中的元素。注意,左添加时,在结果中iterable参数中的顺序将被反过来添加
index(x[, start[, stop]])
: 返回第 x 个元素(从 start 开始计算,在 stop 之前)。返回第一个匹配,如果没找到的话,升起 ValueError
insert(i, x)
: 在位置 i 插入 x, 如果插入会导致一个限长deque超出长度 maxlen 的话,就升起一个 IndexError
pop()
: 移去并且返回一个元素,deque最右侧的那一个。如果没有元素的话,就升起 IndexError 索引错误
popleft()
: 移去并且返回一个元素,deque最左侧的那一个。如果没有元素的话,就升起 IndexError 索引错误
remove(value)
: 移去找到的第一个 value。 如果没有的话就升起 ValueError
reverse()
: 将deque逆序排列。返回 None
rotate(n=1)
: 向右循环移动 n 步。 如果 n 是负数,就向左循环, 如果deque不是空的,向右循环移动一步就等价于 d.appendleft(d.pop()),向左循环一步就等价于 d.append(d.popleft())
Deque对象同样提供了一个只读属性:
maxlen
: Deque的最大尺寸,如果没有限定的话就是 None