deque类
collections.deque 类(双向队列)是一个线程安全、可以快速从两端添加或者删除元素的数据类型。而且如果想要有一种数据类型来存放“最近用到的几个元素”, deque 也是一个很好的选择。这是因为在新建一个双向队列的时候,你可以指定这个队列的大小,如果这个队列满员了,还可以从反向端删除过期的元素,然后在尾端添加新的元素。
deque(maxlen=N)创建一个固定长度的队列,当有新的记录加入到已满的队列时会自动移除最老的那条记录。
>>> from collections import deque
>>> q = deque(range(5), maxlen=5)
>>> q
deque([0, 1, 2, 3, 4], maxlen=5)
>>> q.append(5)
>>> q
deque([1, 2, 3, 4, 5], maxlen=5)
>>> q.rotate(3)
>>> q
deque([3, 4, 5, 1, 2], maxlen=5)
>>> q.appendleft(-1)
>>> q
deque([-1, 3, 4, 5, 1], maxlen=5)
>>> q.extendleft([11,22,33])
>>> q
deque([33, 22, 11, -1, 3], maxlen=5)
- maxlen 是一个可选参数,代表这个队列可以容纳的元素的数量,而且一旦设定,这个属性就不能修改了。
- 队列的旋转操作接受一个参数 n ,当 n > 0 时,队列的最右边的 n 个元素会被移动到队列的左边。当 n < 0 时,最左边的 n 个元素会被移动到右边。
- 当试图对一个已满( len(d) == d.maxlen )的队列做尾部添加操作的时候,它头部的元素会被删除掉。
- extendleft(iter) 方法会把迭代器里的元素逐个添加到双向队列的左边,因此迭代器里的元素会逆序出现在队列里。
Counter
collections.Counter这个映射类型会给键准备一个整数计数器。每次更新一个键的时候都会增加这个计数器。所以这个类型可以用来给可散列表对象计数,或者是当成多重集来用——多重集合就是集合里的元素可以出现不止一次。 Counter 实现了 + 和 - 运算符用来合并记录,还有像most_common([n])这类很有用的方法, most_common([n]) 会按照次序返回映射里最常见的 n 个键和它们的计数,官方文档。
>>> from collections import Counter
>>> c = Counter('asdasdafdsafsadfdsdgxcvsfdagvv')
>>> c
Counter({'d': 7, 'a': 6, 's': 6, 'f': 4, 'v': 3, 'g': 2, 'x': 1, 'c': 1})
>>> c.update('wdaaffdsfsdfsa')
>>> c
Counter({'d': 10, 'a': 9, 's': 9, 'f': 8, 'v': 3, 'g': 2, 'x': 1, 'c': 1, 'w': 1})
关于Counter一个不为人知的特性,那就是它们可以轻松的同各种数学运算操作结合起来使用,如:
这里写代码片
defaultdict
使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict:
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> d['a']
[]
>>> d['a'].append(1)
>>> d
defaultdict(<class 'list'>, {'a': [1]})
>>> d['a'].append(2)
>>> d['b'].append(4)
>>> d
defaultdict(<class 'list'>, {'a': [1, 2], 'b': [4]})
>>> s = 'mississippi'
>>> d = defaultdict(int)
>>> for k in s:
d[k] += 1
>>> sorted(d.items())
[('i', 4), ('m', 1), ('p', 2), ('s', 4)]
OrderedDict
使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。
如果要保持Key的顺序,可以用OrderedDict。当对字典做迭代时候,它会严格按照元素初始添加的顺序进行。
>>> from collections import OrderedDict
>>> d = OrderedDict()
>>> d
OrderedDict()
>>> d['foo'] = 1
>>> d['bar'] = 2
>>> d['spam'] = 3
>>> d['grok'] = 4
>>> for key in d:
... print(key, d[key])
...
foo 1
bar 2
spam 3
grok 4
OrderedDict内部维护了一个双向链表,它会根据元素的加入顺序来排列键的位置。第一个新加入的元素会被放置在链表的末尾,接下来对已存在的键进行赋值时不会改变键的顺序。
- 就没
- 流
namedtuple
collections.namedtuple 是一个工厂函数,它可以用来构建一个带字段名的元组和一个有名字的类——这个带名字的类对调试程序有很大帮助。
>>> from collections import namedtuple
>>> P = namedtuple('P', 'x y')
>>> p = P(1,2)
>>> p.x
1
>>> p.y
2
>>> from collections import namedtuple
>>> City = namedtuple('City', 'name country population coordinates')
>>> tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667))
>>> tokyo
City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722,
139.691667))
>>> tokyo.population
36.933
>>> tokyo.coordinates
(35.689722, 139.691667)
>>> tokyo[1]
'JP'
创建一个具名元组需要两个参数,一个是类名,另一个是类的各个字段的名字。后者可以是由数个字符串组成的可迭代对象,或者是由空格分隔开的字段名组成的字符串。
ChainMap
该类型可以容纳数个不同的映射对象,然后在进行键查找操作的时候,这些对象会被当作一个整体被逐个查找,直到键被找到为止。这个功能在给有嵌套作用域的语言做解释器的时候很有用,可以用一个映射对象来代表一个作用域的上下文。
>>> from collections import ChainMap
>>> a = {'x': 1, 'y': 2}
>>> b = {'y': 3 , 'z': 4}
>>> c = ChainMap(a, b)
>>> c
ChainMap({'x': 1, 'y': 2}, {'y': 3, 'z': 4})
ChainMap可以接受多个映射然后在逻辑上使它们表现为一个单独的映射结构。但是,这些映射在字面上并不会合并在一起。相反,ChainMap只是简单的维护一个记录底层映射关系的列表,然后重新定义常见的字典操作来扫描这个列表。大部分的操作都可以正常的工作。
>>> len(c)
3
>>> c.keys()
KeysView(ChainMap({'x': 1, 'y': 2}, {'y': 3, 'z': 4}))
>>> c.values()
ValuesView(ChainMap({'x': 1, 'y': 2}, {'y': 3, 'z': 4}))
>>> c['x']
1
>>> c['y']
2
如果与重复的键,那么这里会采用第一个映射中所对应的键值。
修改映射的操作总会作用在列出的第一个映射结构上。
>>> c['y'] = 22
>>> c['z'] = 9
>>> del c['x']
>>> a
{'y': 22, 'z': 9}
>>> c
ChainMap({'y': 22, 'z': 9}, {'y': 3, 'z': 4})
注:ChainMap使用的是原始的字典,也就是说如果任一个原始的字典发生了变化,那么合并之后的字典也将会发生变化
>>> a['a'] = 4
>>> a
{'y': 22, 'z': 9, 'a': 4}
>>> c
ChainMap({'y': 22, 'z': 9, 'a': 4}, {'y': 3, 'z': 4})
而作为ChainMap的替代方案,可能会考虑到利用字典的update()方法将多个字典合并在一起。
>>> a
{'y': 22, 'z': 9, 'a': 4}
>>> b
{'x':3}
>>> merged = dict(b)
>>> merged.update(a)
>>> merged
{'y': 22, 'z': 9, 'a': 4, 'x': 3}
>>>
但是,如果其中任意一个原始字典发生了改变,这个改变都不会反应到合并后的字典中。
>>> a['x'] = 5
>>> a
{'y': 22, 'z': 9, 'a': 4, 'x': 5}
>>> b
{'x': 3}
>>> merged
{'y': 22, 'z': 9, 'a': 4, 'x': 3}
本文介绍Python标准库中的高效数据结构,包括双向队列(deque)、计数器(Counter)、默认字典(defaultdict)、有序字典(OrderedDict)、具名元组(namedtuple)及链式映射(ChainMap),并展示了它们的典型应用场景。
1535

被折叠的 条评论
为什么被折叠?



