python中的collections模块

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记住了插入顺序。

后端开发标签