1. 介绍
Collections是Python标准库中的一个模块,提供了一些有用的集合类,扩展了Python内置的数据结构,如字典、列表、元组等。它包含的集合类有Counter,deque,defaultdict,namedtuple,OrderedDict等,这些类提供的功能在实际开发中非常有用。
Collections模块中提供的类可以用来解决很多实际问题,比如计数、排序、过滤、分组、按键排序等等。本文将重点介绍Collections模块中的几个重要的类。
2. Counter #2个重点
2.1 简介
Counter是一个容器,用于跟踪值的出现次数。它提供了一个非常方便的方法,可以使用简单的语法来计数。
2.2 用法示例 #3个重点
例如,计算一个列表中所有元素出现的次数:
from collections import Counter
lst = [1,2,2,3,3,3,4,4,4,4]
c = Counter(lst)
print(c)
输出:
Counter({4: 4, 3: 3, 2: 2, 1: 1})
可以看到,输出结果是一个字典,它的键是原始列表中的元素,值是该元素出现的次数。通过这种方式,我们可以轻松地计算一个列表中每个元素的出现次数。
Counter类还有其他一些非常有用的方法,例如most_common(),返回出现最多的元素及其数量:
from collections import Counter
lst = [1,2,2,3,3,3,4,4,4,4]
c = Counter(lst)
print(c.most_common())
print(c.most_common(2))
输出:
[(4, 4), (3, 3), (2, 2), (1, 1)]
[(4, 4), (3, 3)]
most_common()返回一个元素为(值,计数)对的列表,按照计数从高到低排序。
2.3 注意事项 #1个重点
需要注意的是,Counter类在跟踪数据出现次数时,计数是增加的,不会减少。
例如,从下面的代码可以看出,从Counter实例中删除key不存在的元素,不会对计数造成影响:
from collections import Counter
c = Counter(a=3, b=2)
print(c)
del c['a']
print(c)
del c['a']
print(c)
输出:
Counter({'a': 3, 'b': 2})
Counter({'b': 2})
Counter({'b': 2})
需要删除计数为0的元素,使用subtract()方法:
from collections import Counter
c = Counter(a=3, b=2)
print(c)
c.subtract({'a': 1, 'b': 2})
print(c)
输出:
Counter({'a': 3, 'b': 2})
Counter({'a': 2})
3. defaultdict
3.1 简介
defaultdict是dict的子类,它覆盖了一个方法并添加了一个可写的实例变量。
当使用一个不存在的键访问字典时,defaultdict会通过调用工厂函数来返回一个默认值。
3.2 用法示例 #2个重点
示例一:
from collections import defaultdict
d = defaultdict(int)
d['a'] = 1
print(d['a'])
print(d['b'])
输出:
1
0
因为字典中没有键为'b'的元素,默认工厂函数int()返回0。
示例二:
from collections import defaultdict
d = defaultdict(list)
d['a'].append(1)
print(d['a'])
print(d['b'])
输出:
[1]
[]
因为字典中没有键为'b'的元素,默认工厂函数list()返回一个空列表[]。
3.3 注意事项 #1个重点
需要注意的是,在setdefault()方法和defaultdict工厂函数之间完全等效。defaultdict提供了一个更简洁的方法来实现,这在某些情况下可能很有用。
4. deque
4.1 简介
deque(double-ended queue)是一个可以从两端操作的序列。
与列表(list)比较,deque具有以下优点:
当需要快速添加或删除的元素时,可以使用deque,而不是在列表的开头进行插入和删除操作,因为这样可能会导致列表中的其他元素的移位。
当需要遍历元素时,列表比deque快,因为列表中的元素在内存中是连续存储的,而deque中的元素在内存中并不总是相邻存储的。
4.2 用法示例
deque的用法与列表类似,可以在任意一端添加或删除元素。下面的示例演示如何使用deque来实现一个队列。
from collections import deque
q = deque()
q.append(1)
q.append(2)
q.append(3)
print(q)
print(q.popleft())
print(q.popleft())
print(q.popleft())
print(q)
输出:
deque([1, 2, 3])
1
2
3
deque([])
4.3 注意事项
deque除了支持列表中的方法之外,还支持一些其他的方法,如在任意一端添加或删除多个元素,旋转队列等。
5. namedtuple
5.1 简介
namedtuple本质上是一个创建Python类的工厂函数。
它接受两个参数,一个是新类的名称,另一个是这个新类的各个字段的名称和类型。它返回一个类,可以像一个普通的Python类一样创建一个实例。
5.2 用法示例
示例一:
from collections import namedtuple
Person = namedtuple('Person', ['name', 'age', 'gender'])
p1 = Person('张三', 20, '男')
p2 = Person('李四', 30, '女')
print(p1)
print(p2)
print(p1.name)
print(p2.age)
输出:
Person(name='张三', age=20, gender='男')
Person(name='李四', age=30, gender='女')
张三
30
示例二:
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(1, 2)
print(p)
print(p.x)
print(p.y)
输出:
Point(x=1, y=2)
1
2
5.3 注意事项
namedtuple的实例没有自己的字典,它们使用与元组相同的紧凑表示。这使得它们更快,消耗的内存更少,但是也意味着一旦创建后,实例的字段是无法更改的。
如果需要修改字段,可以使用_replace()方法创建一个新的实例。
6. OrderedDict
6.1 简介
OrderedDict是dict的子类,它记住了插入顺序。
6.2 用法示例
示例一:
from collections import OrderedDict
d = OrderedDict()
d['foo'] = 1
d['bar'] = 2
d['spam'] = 3
d['grok'] = 4
for key, value in d.items():
print(key, value)
输出:
foo 1
bar 2
spam 3
grok 4
示例二:
import json
from collections import OrderedDict
d = OrderedDict()
d['foo'] = 1
d['bar'] = 2
d['spam'] = 3
d['grok'] = 4
print(json.dumps(d))
输出:
{"foo": 1, "bar": 2, "spam": 3, "grok": 4}
6.3 注意事项
OrderedDict的内部结构是一个哈希表和一个双向链表。因此,相对于普通的字典,它可能需要更多的内存空间。
总结
Collections模块提供了一种扩展Python内置数据结构的方式,使得程序员可以更方便地解决实际问题。本文主要介绍了Collections模块中的五个常用类,包括Counter、defaultdict、deque、namedtuple和OrderedDict。
Counter是一个容器,用于跟踪值的出现次数;defaultdict提供了一个可写的实例变量,当使用一个不存在的键访问字典时,defaultdict会通过调用工厂函数来返回一个默认值;deque是一个可以从两端操作的序列;namedtuple是一个创建Python类的工厂函数;OrderedDict记住了插入顺序。