Use of the collections module

The collections module implements some specialized containers based on the built-in dict, list, set, and tuple data types in Python to extend the functionality of variables of these basic types.

namedtuple

The original tuple can only access the elements contained in the index method. The namedtuple is equivalent to taking a new name for the elements in the tuple and tuple. You can use these names to access directly when operating (this operation seems to be similar to that in C. struct is pretty much the same). This setup makes the purpose of defining the tuple variable clear at a glance, so making good use of it can make our code easier to maintain. Let's see how to use it!

# 现在我们想要定义一个类型专门用于保存坐标
# 构造一个类专门去保存好像有点麻烦
# 这时namedtuple就派上用场啦

# 执行结果在下方
from collections import namedtuple
Posi = namedtuple('Positions', ('x', 'y'))
p = Posi(1, 2)	# 创建对象时记住要用Posi,Positions只是一个标识的名称
print(p)
# Positions(x=1, y=2)
print(p.x, p.y)	# 记住tuple是不可修改的,所以不能给p.x重新赋值
# 1 2

That's right, the instantiated object prints the name we defined for it earlier, and the element name can also be obtained by using the name we gave. Compared with the old-fashioned tuple, the namedtuple is simply too intimate, and the effect can be seen at a glance.

about

Deque is a method to extend the function of list. To put it bluntly, it is to change the list into a double-ended queue, which can be used for stacks and queues. Although the list object also supports similar operations, because the time complexity of inserting and deleting elements in linear storage is O(n), it is inefficient when the amount of data is large. There are many operation methods in deque:

from collections import deque
que1 = deque([1,2,3,4,5])
que1.append(5)		# 向右添加元素
print(que1)
# deque([1, 2, 3, 4, 5, 5])
que1.appendleft(0)		# 向左添加元素
print(que1)
# deque([0, 1, 2, 3, 4, 5, 5])
que2 = que1.copy()		# 浅拷贝一个deque对象
print(que1,que2)
# deque([0, 1, 2, 3, 4, 5, 5]) deque([0, 1, 2, 3, 4, 5, 5])
que1.clear()	# 清空deque中元素
print(que1)
#deque([])
print(que2.count(5))	# 统计某一个元素的个数
# 2
que2.extend([6,7])		# 从右合并
que2.extendleft([-1,-2])	# 往左扩展时是倒序合并
print(que2)
# deque([-2, -1, 0, 1, 2, 3, 4, 5, 5, 6, 7])
que2.insert(4,1)	# 向指定位置插入元素,前一个参数为位置,后一个为值
print(que2)
# deque([-2, -1, 0, 1, 1, 2, 3, 4, 5, 5, 6, 7])
que2.pop()	# 右弹出值
que2.popleft()	# 坐弹出值
print(que2)
# deque([-1, 0, 1, 1, 2, 3, 4, 5, 5, 6])
que2.remove(1)	# 删除第一个找到的值
print(que2)
# deque([-1, 0, 1, 2, 3, 4, 5, 5, 6])
que2.reverse()
print(que2)		# 将deque对象中的元素倒排
# deque([6, 5, 5, 4, 3, 2, 1, 0, -1])
que2.rotate(2)		# 将右边的N个元素弹出并插入到左边
print(que2)
# deque([0, -1, 6, 5, 5, 4, 3, 2, 1])

ChainMap

ChainMap provides a strategy that can handle multiple maps as a unit. It is often much faster than creating a new dictionary and then merging the originals with update(). It should be noted that ChainMap merges the elements in all mapping objects by reference, so when the elements in the original mapping object change, the content in the merged object will also change.

from collections import ChainMap

attr1 = {'name':'Tom','Age':18}
attr2 = {'gender':'man','addr':'Beijing'}
people = ChainMap(attr1,attr2)	# 合并两个字典
print(people)
# ChainMap({'name': 'Tom', 'Age': 18}, {'addr': 'Beijing', 'gender': 'man'})
print(people['name'])
# Tom
attr1['name'] = 'Micheal'
print(attr1['name'], people['name'])	# 修改原字典中的值,合并后列表中的值也会改变
# Micheal Micheal
people = people.new_child({'country':'America'})	# new_child为ChainMap实例合并新字典
print(people)
# ChainMap({'country': 'America'}, {'name': 'Micheal', 'Age': 18}, {'addr': 'Beijing', 'gender': 'man'})
print(people.parents)		# parents属性指定的是父级内容,即实例变化前的内容
# ChainMap({'name': 'Micheal', 'Age': 18}, {'addr': 'Beijing', 'gender': 'man'})
print(people.parents.parents)		# 父级的父级内容
#ChainMap({'addr': 'Beijing', 'gender': 'man'})
print(people.maps)		# maps属性返回的是将合并后的ChainMap实例拆分并保存为list的结果,是最新的结果
# [{'country': 'America'}, {'name': 'Micheal', 'Age': 18}, {'addr': 'Beijing', 'gender': 'man'}]
print(people)
# ChainMap({'country': 'America'}, {'name': 'Micheal', 'Age': 18}, {'addr': 'Beijing', 'gender': 'man'})

counter

Counter provides a convenient and fast counter. The counted count is stored in a dictionary, the field is stored as a key, and the number of occurrences is stored as a value. Counter can read the count of any field. The default count of non-existent fields is 0, and the value can also be negative. The method of use is as follows:

from collections import Counter

c1 = Counter('hello world')
print(c1)
# Counter({'l': 3, 'o': 2, ' ': 1, 'e': 1, 'w': 1, 'h': 1, 'd': 1, 'r': 1})
c2 = Counter({'man':4, 'woman':2})
print(c2)
# Counter({'man': 4, 'woman': 2})
c3 = Counter(child=3, young=1,old=2)
print(c3.most_common(2))	# most_common方法会返回计数排名前N的元素
# [('child', 3), ('old', 2)]
print(list(c3.elements()))	# elements方法返回一个迭代器,里面包含所有的key,数量与计数对应
# ['young', 'old', 'old', 'child', 'child', 'child']
c4 = Counter(child=2,young=1,old=1)
c3.subtract(c4)		# subtract方法用于从一个counter中减掉另一个counter,key相同时对计数做减法
print(c3)
# Counter({'old': 1, 'child': 1, 'young': 0})
c5 = Counter(middle=3)
c4.subtract(c5)
print(c4)
# Counter({'child': 2, 'young': 1, 'old': 1, 'middle': -3})
del c3['child']	# del用于从字典中删除某一个元素,这类操作同样适用于Counter实例
print(c3['child'])
# 0

fruits1 = Counter({'apple':3,'orange':5,'banana':7})
fruits2 = Counter({'orange':2,'apple':1,'pear':4})
print(fruits1 - fruits2)	# Counter实例还可进行加减运算和按位与或
# Counter({'banana': 7, 'orange': 3, 'apple': 2})
print(fruits1 + fruits2)
# Counter({'banana': 7, 'orange': 7, 'pear': 4, 'apple': 4})
print(fruits1 & fruits2)
# Counter({'orange': 2, 'apple': 1})
print(fruits1 | fruits2)
# Counter({'banana': 7, 'orange': 5, 'pear': 4, 'apple': 3})

It should also be noted that some general operations on dictionaries also work on Counters. But fromkeys() cannot act on Counter instances here, and update() is here to add a new Counter instead of replacing the old one. These two methods are exceptions.

OrderDict

Regular dicts are stored randomly, which makes it impossible to determine the order of elements when we iterate over the dict. OrderDict can effectively solve this problem, but returns the order in which it was inserted, instead of sorting according to the key (if the elements are defined at the beginning, the output is in random order).

from collections import OrderedDict
d = OrderedDict(a=1,b=2,c=3)
print(d)
# OrderedDict([('c', 3), ('a', 1), ('b', 2)])
print(d)
# OrderedDict([('c', 3), ('a', 1), ('b', 2)])
d['d'] = 4
print(d)
# OrderedDict([('c', 3), ('a', 1), ('b', 2), ('d', 4)])
print(d)	# 元素按照固定顺序排列
# OrderedDict([('c', 3), ('a', 1), ('b', 2), ('d', 4)])
d = OrderedDict.fromkeys('abbcde')
print(d)
# rderedDict([('a', None), ('b', None), ('c', None), ('d', None), ('e', None)])
d.move_to_end('b')		# 将指定元素移动到末尾
print(d.keys())
# odict_keys(['a', 'c', 'd', 'e', 'b'])
d.move_to_end('d',last=False)		# 将指定元素移动到头部
print(d.keys())
# odict_keys(['d', 'a', 'c', 'e', 'b'])
d.popitem()		# 移除末尾元素
print(d.keys())
# odict_keys(['d', 'a', 'c', 'e'])
d.popitem(last=False)		# 移除首部元素
print(d.keys())
# dict_keys(['a', 'c', 'e'])

defaultdict

For a normal dict, if you try to access a non-existing Key, a KeyError will be thrown. If you want to return a default value when the Key does not exist, then defaultdict comes in handy. (note that the default value is brought back by calling the function)

from collections import defaultdict
dd = defaultdict(lambda : 0)
dd['a'] = 1
print(dd['a'])
# 1
print(dd['b'])
# 0

UserDict

User-defined dictionary class, which can be inherited and rewritten rules. It can be used to copy the data of a dictionary during initialization, rather than simply referencing it.

from collections import UserDict
dict = {'a':1,'b':2}
ud = UserDict(dict)
print(dict, ud)
# {'b': 2, 'a': 1} {'b': 2, 'a': 1}
ud['c'] = 3
print(dict, ud)
# {'b': 2, 'a': 1} {'c': 3, 'b': 2, 'a': 1}

UserList

User-defined list class that can inherit from this class and override rules. Build a user-defined list and copy the contents of another list during initialization.

from collections import UserList
li = [1,2,3,4]
l = li
ul = UserList(li)
del li[0]
print(l, li, ul)
# [2, 3, 4] [2, 3, 4] [1, 2, 3, 4]

UserString

User-defined string class, which can be inherited and rewritten rules. A string can be copied during initialization.

from collections import UserString

s = 'hello world!'
us = UserString(s)
print(s, us)
# hello world! hello world!

Please indicate the source of the reprint, if there is anything wrong, please correct it, thank you

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325441104&siteId=291194637