Python中collections模块包含一些容器数据类型。
import collections
[x for x in dir(collections) if not x.startswith('_')]
# 结果:
['ChainMap', 'Counter', 'OrderedDict', 'UserDict', 'UserList', 'UserString',
'abc', 'defaultdict', 'deque', 'namedtuple']
搜索多个字典,按字典出现顺序搜索。
m=collections.ChainMap(字典1,字典2,字典3,...):管理多个字典,提供上下文容器,可看作栈。
m.maps:映射列表。字典组成的列表。搜索到的值是按顺序找到第一个映射中的值。可改变顺序。
import collections
a = {"a":"A","b":"B"}
b = {"c":"C","b":"D"}
m = collections.ChainMap(a,b)
m # 结果:ChainMap({'a': 'A', 'b': 'B'}, {'c': 'C', 'b': 'D'})
# 映射列表
m.maps # 结果:[{'a': 'A', 'b': 'B'}, {'c': 'C', 'b': 'D'}]
# 获取键的值,返回按顺序找到的第一个映射中的值
m["a"] # 结果:'A'
m["b"] # 结果:'B'
m["c"] # 结果:'C'
list(m.keys()) # 结果:['c', 'b', 'a']
list(m.values()) # 结果:['C', 'B', 'A']
list(m.items()) # 结果:[('c', 'C'), ('b', 'B'), ('a', 'A')]
# 改变顺序(也会改变搜索结果)
m.maps = list(reversed(m.maps))
m # 结果:ChainMap({'c': 'C', 'b': 'D'}, {'a': 'A', 'b': 'B'})
m["b"] # 结果:'D'
# 修改值(只修改找到的第一个映射中的值)
m["b"] = "w"
m # 结果:ChainMap({'c': 'C', 'b': 'w'}, {'a': 'A', 'b': 'B'})
new_child()方法用一个额外的映射在maps列表最前面创建新映射,可将新的映射作为new_child()方法的参数。避免修改现有的底层数据结构。
import collections
a = {"a":"A","b":"B"}
b = {"c":"C","b":"D"}
m = collections.ChainMap(a,b)
m # 结果:ChainMap({'a': 'A', 'b': 'B'}, {'c': 'C', 'b': 'D'})
mn = m.new_child()
mn["b"] = "w"
mn # 结果:ChainMap({'b': 'w'}, {'a': 'A', 'b': 'B'}, {'c': 'C', 'b': 'D'})
# 或者
c = {"b":"w"}
mq = m.new_child(c)
mq # 结果:ChainMap({'b': 'w'}, {'a': 'A', 'b': 'B'}, {'c': 'C', 'b': 'D'})
字典子类,对可哈希对象计数。用字典形式统计元素及其在序列中出现的次数。
参考:collections模块Counter
字典子类,记住添加的键的顺序。
# 普通字典
c ={}
c[1]="a"
c[2]="b"
c[3]="c"
d = {}
d[3]="c"
d[2]="b"
d[1]="a"
c == d # 结果:True
c # 结果:{1: 'a', 2: 'b', 3: 'c'}
d # 结果:{3: 'c', 2: 'b', 1: 'a'}
# OrderedDict
import collections
a = collections.OrderedDict()
a[1]="a"
a[2]="b"
a[3]="c"
b = collections.OrderedDict()
b[3]="c"
b[2]="b"
b[1]="a"
a==b # 结果:False
a # 结果:OrderedDict([(1, 'a'), (2, 'b'), (3, 'c')])
b # 结果:OrderedDict([(3, 'c'), (2, 'b'), (1, 'a')])
用move_to_end()方法可以将元素移到末尾(last=True)或起始(last=False)位置。
import collections
a = collections.OrderedDict()
a[1]="a"
a[2]="b"
a[3]="c"
a # 结果:OrderedDict([(1, 'a'), (2, 'b'), (3, 'c')])
# 将键2移到末尾位置
a.move_to_end(2)
a # 结果:OrderedDict([(1, 'a'), (3, 'c'), (2, 'b')])
# 将键3移到起始位置
a.move_to_end(3,last=False)
a # 结果:OrderedDict([(3, 'c'), (1, 'a'), (2, 'b')])
字典子类,调用工厂函数来提供缺失值。
工厂函数提前设定默认值。将工厂函数作为defaultdict的参数。若没有键,则调用工厂函数返回默认值。
import collections
def default_factory():
return "default value"
a = collections.defaultdict(default_factory)
a["a"] = 9
a # 结果:defaultdict(, {'a': 9})
a["a"] # 结果:9
a["b"] # 'default value'
a # 结果:defaultdict(, {'a': 9, 'b': 'default value'})
import collections
m = collections.defaultdict(int)
m["a"] = 9
m # 结果:defaultdict(, {'a': 9})
m["a"] # 结果:9
m["b"] # 0
m # 结果:defaultdict(, {'a': 9, 'b': 0})
n = collections.defaultdict(list)
n["a"].append(9)
n # 结果:defaultdict(, {'a': [9]})
n["a"] # 结果:[9]
n["b"] # []
n # 结果:defaultdict(, {'a': [9], 'b': []})
两端都可以添加和移除。
参考:collections模块deque
创建具有命名字段的元组子类。collections.namedtuple(元组子类名称,[ 命名字段1, 命名字段2,...])
普通元组:用索引访问元组中的元素。命名元组:用命名字段访问元素。
命名元组 创建的类不是使用实例字典,能更高效地使用内存;但属性访问没有类那么高效,且字段数量不方便增加。
所有普通元组的操作在命名元组中仍然有效。
import collections
Mytuple = collections.namedtuple('Mytuple',['name','age'])
people1 = Mytuple('Jack',18)
people1.name # 结果:'Jack'
people1.age # 结果:18
people1 # 结果:Mytuple(name='Jack', age=18)
people2 = Mytuple(name='Tom',age=33)
people2.name # 结果:'Tom'
people2.age # 结果:33
people2 # 结果:Mytuple(name='Tom', age=33)
# 相当于
class Mytuple(object):
def __init__(self,name,age):
self.name = name
self.age = age
people1 = Mytuple('Jack',18)
people1.name # 结果:'Jack'
people1.age # 结果:18
people2 = Mytuple('Tom',33)
people2.name # 结果:'Tom'
people2.age # 结果:33
命名元组和普通元组都不能修改。但命名元组可以用_replace()方法创建新实例 替换某字段的值。
import collections
Mytuple = collections.namedtuple('Mytuple',['name','age'])
people1 = Mytuple('Jack',18)
people1.name # 结果:'Jack'
people1.age # 结果:18
people1 # 结果:Mytuple(name='Jack', age=18)
people2 = people1._replace(age=20)
people2.name # 结果:'Jack'
people2.age # 结果:20
people2 # 结果:Mytuple(name='Jack', age=20)
用_asdict()方法可以将namedtuple实例转为OrderedDict实例。且OrderedDict的键和namedtuple字段的顺序相同。
import collections
Mytuple = collections.namedtuple('Mytuple',['name','age'])
people1 = Mytuple('Jack',18)
people1 # 结果:Mytuple(name='Jack', age=18)
people1._asdict() # 结果:{'name': 'Jack', 'age': 18}
容器的抽象基类。为Python内置容器数据结构和collections模块定义的容器数据结构定义了API。
import collections
[x for x in dir(collections.abc) if not x.startswith('_')]
# 结果:
['AsyncGenerator', 'AsyncIterable', 'AsyncIterator', 'Awaitable', 'ByteString',
'Callable', 'Collection', 'Container', 'Coroutine', 'Generator', 'Hashable',
'ItemsView', 'Iterable', 'Iterator', 'KeysView', 'Mapping', 'MappingView',
'MutableMapping', 'MutableSequence', 'MutableSet', 'Reversible', 'Sequence',
'Set', 'Sized', 'ValuesView']
字典对象的包装器,便于字典子类化。
列表对象的包装器,便于列表子类化。
字符串对象的包装器,便于字符串子类化。
补充:collections — Container datatypes — Python 3.12.0 documentation