目录
这个模块实现了特定目标的容器,以提供Python 标准内建容器dict , list , set , 和tuple 的替代选择
ChainMap 对象
- ChainMap 非常强大的dict字典组合功能,他将多个dict字典放入到一个list中,他比dict字典使用update快很多。通过ChainMap可以来模拟嵌套的情景,而且多用于模板之中
from collections import ChainMap
m1 = {'Type': 'admin', 'codeID': '00001'}
m2 = {'name': 'woodname', 'codeID': '00002'}
m = ChainMap(m1, m2)
print(m)
# 输出:
# ChainMap({'Type': 'admin', 'codeID': '00001'}, {'name': 'woodname', 'codeID': '00002'})
print(m.maps)
# 输出:[{'Type': 'admin', 'codeID': '00001'}, {'name': 'woodname', 'codeID': '00002'}]
for i in m.items():
print(i)
# 输出:
# ('name', 'woodname')
# ('codeID', '00001')
# ('Type', 'admin')
print(m['name']) # 读取元素的值
print(m['codeID']) # 注意,当key重复时以最前一个为准
print(m.get('Type'))
# 输出:
# woodname
# 00001
# admin
# 新增map
m3 = {'data': '888'}
m = m.new_child(m3) # 将 m3 加入m
print(m)
# 输出:
# ChainMap({'data': '888'}, {'Type': 'admin', 'codeID': '00001'}, {'name': 'woodname', 'codeID': '00002'})
print(m.parents) # m 的父亲
# 输出:ChainMap({'Type': 'admin', 'codeID': '00001'}, {'name': 'woodname', 'codeID': '00002'})
print(m.parents.parents)
# 输出 : ChainMap({'name': 'woodname', 'codeID': '00002'})
Counter 对象
class collections.Counter([iterable-or-mapping ])
- 一个Counter 是一个dict 的子类,用于计数可哈希对象。它是一个集合,元素像字典键(key) 一样存储,它们的计数存储为值。计数可以是任何整数值,包括0 和负数。
- 创建一个 Counter:
from collections import Counter
c = Counter() # 创建一个新的空counter
c = Counter('abcasdf') # 一个迭代对象生成的counter
c = Counter({'red': 4, 'yello': 2}) # 一个映射生成的counter
c = Counter(cats=2, dogs=5) # 关键字参数生成的counter
# counter 生成counter, 虽然这里并没有什么用
c = Counter('abcasd')
print(c) # Counter({'a': 2, 'c': 1, 'b': 1, 's': 1, 'd': 1})
c2 = Counter(c)
print(c2) # Counter({'a': 2, 'c': 1, 'b': 1, 's': 1, 'd': 1})
- 因为 Counter 实现了字典的 missing 方法, 所以当访问不存在的key的时候,返回值为0:
from collections import Counter
c = Counter(['apple', 'pear'])
print(c['orange']) # 0
设置一个计数为0 不会从计数器中移去一个元素。使用del 来删除它:
>>> c['sausage'] = 0
>>> del c['sausage']
elements()
- 按照counter的计数,重复返回元素
from collections import Counter
c = Counter(a=4, b=2, c=0, d=-2)
print(list(c.elements()))
most_common([n ])
- 按照counter的计数,按照降序,返回前n项组成的list; n忽略时返回全部
from collections import Counter
c = Counter('abracadabra')
print(c)
print(c.most_common(3))
subtract([iterable-or-mapping ])
- counter按照相应的元素,计数相减
from collections import Counter
c = Counter(a=4, b=2, c=0, d=-2)
d = Counter(a=1, b=2, c=3, d=4)
c.subtract(d)
print(c) # Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})
total()
- 计算总计数值,3.10 新版功能.
>>> c = Counter(a=10, b=5, c=0)
>>> c.total()
15
update([iterable-or-mapping ])
- update([iterable-or-mapping])不同于字典的update方法,这里更新counter时,相同的key的value值相加而不是覆盖
import collections
x1 = collections.Counter({'a': 1, 'b': 2})
x2 = collections.Counter(a=1, b=2)
x1.update(x2) # Counter()类型 isinstance(iterable, Mapping) 也返回 True
# 或者这样调用
x1 = collections.Counter({'a': 1, 'b': 2})
x1.update('aab')
print(x1) # Counter({'a': 3, 'b': 3})
Counter 间的数学集合操作
>>> c = Counter(a=3, b=1, c=5)
>>> d = Counter(a=1, b=2, d=4)
>>> c + d # counter相加, 相同的key的value相加
Counter({'c': 5, 'a': 4, 'd': 4, 'b': 3})
>>> c - d # counter相减, 相同的key的value相减,只保留正值得value
Counter({'c': 5, 'a': 2})
>>> c & d # 交集: 取两者都有的key,value取小的那一个
Counter({'a': 1, 'b': 1})
>>> c | d # 并集: 汇聚所有的key, key相同的情况下,取大的value
Counter({'c': 5, 'd': 4, 'a': 3, 'b': 2})
常见做法:
sum(c.values()) # 继承自字典的.values()方法返回values的列表,再求和
c.clear() # 继承自字典的.clear()方法,清空counter
list(c) # 返回key组成的list
set(c) # 返回key组成的set
dict(c) # 转化成字典
c.items() # 转化成(元素,计数值)组成的列表
Counter(dict(list_of_pairs)) # 从(元素,计数值)组成的列表转化成Counter
c.most_common()[:-n-1:-1] # 最小n个计数的(元素,计数值)组成的列表
c += Counter() # 利用counter的相加来去除负值和0的值
deque 对象
- list 列表 存储数据时,使用索引访问元素时很快,但插入和删除元素很慢,因为 list 列表 是线性存储数据,数据量越大插入和删除的效率越低。
- deque 为双向列表,它能高效实现插入和删除操作。
from collections import deque
# append
# appendleft
dlist = deque([1, 'a'])
dlist.append('b') # 在末尾加数据
dlist.appendleft(0) # 在最前端插入数据
print(dlist) # 输出 : deque([0, 1, 'a', 'b'])
# pop
# popleft
dlist.pop() # 删除末尾的数据
dlist.popleft() # 删除最前端的数据
print(dlist) # 输出 : deque([1, 'a'])
# extend
# extendleft
dlist.extend(['b', 'c']) # 在末尾追加list 数据
dlist.extendleft([-1, 0]) # 在前端插入list 数据
print(dlist) # 输出 : deque([0, -1, 1, 'a', 'b', 'c'])
# index
print(dlist.index('a')) # 找出 a 的索引位置 # 输出 : 3
# insert
dlist.insert(2, 555) # 在索引2 的位置插入555
print(dlist) # 输出 : deque([0, -1, 555, 1, 'a', 'b', 'c'])
# count
print(dlist.count('a')) # 查找 ‘a’ 的数量
# remove
dlist.remove(1) # 删除第一个匹配值
# reverse
dlist.reverse() # 反向
print(dlist) # 输出 : deque(['c', 'b', 'a', 555, -1, 0])
# rotate 将右端的元素移动到左端。如果n是负数,就将左端的元素移动到右端
dlist.rotate(-2) # 将左端的元素移动到右端
print(dlist) # 输出 : deque(['a', 555, -1, 0, 'c', 'b'])
dlist.rotate(2) # 将右端的元素移动到左端
print(dlist) # 输出 : deque(['c', 'b', 'a', 555, -1, 0])
# copy
dl1 = dlist # 赋值 dlist 值变化,dl1的值也会修改
dl2 = dlist.copy() # 拷贝 dlist, 拷贝后对dl修改不影响dlist的值
dlist.pop() # 删除最后一个数据, dl1的值也被修改
print(dl1) # 输出: deque(['c', 'b', 'a', 555, -1])
print(dl2) # 输出: deque(['c', 'b', 'a', 555, -1, 0])
# clear
d = deque()
d.append(1)
d.clear()
print(d) # deque([])
# maxlen
# Deque 的最大尺寸,如果没有限定的话就是None 。
d.maxlen(5)
defaultdict 对象
当我使用普通的字典时,用法一般是dict={},添加元素的只需要dict[element] =value即,调用的时候也是如此,dict[element] = xxx,但前提是element字典里,如果不在字典里就会报错,如:
dict = {'a':1}
print(dict['b'])
"""
Traceback (most recent call last):
File "C:\Users\Desktop\新建文件夹\q.py", line 2, in <module>
print(dict['b'])
KeyError: 'b'
"""
这时defaultdict就能排上用场了,defaultdict的作用是在于,当字典里的key不存在但被查找时,返回的不是keyError而是一个默认值
defaultdict接受一个工厂函数作为参数,如下来构造:
dict =defaultdict( factory_function)
这个factory_function可以是list、set、str等等,作用是当key不存在时,返回的是工厂函数的默认值,比如list对应[ ],str对应的是空字符串,set对应set( ),int对应0,如下举例:
from collections import defaultdict
dict1 = defaultdict(int)
dict2 = defaultdict(set)
dict3 = defaultdict(str)
dict4 = defaultdict(list)
dict1[2] ='two'
print(dict1[1])
print(dict2[1])
print(dict3[1])
print(dict4[1])
"""
输出:
0
set()
[]
"""
namedtuple() 命名元组的工厂函数
collections.namedtuple
- collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)
- 使用实例:
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(11,y=2)
print(p[0] + p[1])
a,b = p
print(a,b)
print(p.x + p.y)
print(p)
例子2:
import collections
Person = collections.namedtuple('Person', 'name age gender')
Bob = Person(name='Bob', age=30, gender='male')
Jane = Person(name='Jane', age=29, gender='female')
print('Field by Name:', Jane.name)
for people in [Bob, Jane]:
print("%s is %d years old %s" % people)
"""
Field by Name: Jane
Bob is 30 years old male
Jane is 29 years old female
"""
实际应用:
- 命名元组尤其有用于赋值csv sqlite3 模块返回的元组
from collections import namedtuple
EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')
import csv
for emp in map(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):
print(emp.name, emp.title)
- 赋值数据库返回
from collections import namedtuple
EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')
import sqlite3
conn = sqlite3.connect('/companydata')
cursor = conn.cursor()
cursor.execute('SELECT name, age, title, department, paygrade FROM employees')
for emp in map(EmployeeRecord._make, cursor.fetchall()):
print(emp.name, emp.title)
classmethod somenamedtuple._make(iterable)
- 类方法从存在的序列或迭代实例创建一个新实例
>>> t = [11, 22]
>>> Point._make(t)
Point(x=11, y=22)
somenamedtuple._asdict()
- 返回一个新的dict ,它将字段名称映射到它们对应的值
>>> p = Point(x=11, y=22)
>>> p._asdict()
{'x': 11, 'y': 22}
somenamedtuple._replace(**kwargs)
- 返回一个新的命名元组实例,并将指定域替换为新的值
>>> p = Point(x=11, y=22)
>>> p._replace(x=33)
Point(x=33, y=22)
somenamedtuple._fields
- 字符串元组列出了字段名。用于提醒和从现有元组创建一个新的命名元组类型。
>>> p._fields
('x', 'y')
>>> Color = namedtuple('Color', 'red green blue')
>>> Pixel = namedtuple('Pixel', Point._fields + Color._fields)
>>> Pixel(11, 22, 128, 255, 0)
Pixel(x=11, y=22, red=128, green=255, blue=0)
somenamedtuple._field_defaults
- 字典将字段名称映射到默认值。
from collections import namedtuple
Account = namedtuple('Account', ['type', 'balance'], defaults=[0])
print(Account._field_defaults) # {'balance': 0}
print(Account('premium')) # Account(type='premium', balance=0)