collections 模块提供了许多高性能的数据类型。
什么是 collections
模块?
collections
模块是Python标准库的一部分,它包含了一些专门用于处理数据集合的容器数据类型。这些数据类型在功能上对Python内置的 list
、dict
、tuple
和 set
等数据类型进行了扩展和优化。通过使用 collections
模块,我们可以更方便地处理各种数据操作,例如统计元素出现的次数、保持插入顺序的字典、具有默认值的字典等等。
要使用 collections
模块,我们需要先导入它:
import collections
下面是 collections
模块中一些常用的数据类型:Counter
、OrderedDict
、defaultdict
、namedtuple
和 deque
。
Counter
类
Counter
是一个用于统计可迭代对象中元素出现次数的工具。它是一个字典的子类,键是元素,值是元素出现的次数。
在实际应用中,统计文本中单词出现的频率、统计列表中元素的出现次数等场景都非常适合使用 Counter
。
示例代码
from collections import Counter
# 统计列表中元素的出现次数
my_list = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
counter = Counter(my_list)
print(counter)
# 输出:Counter({4: 4, 3: 3, 2: 2, 1: 1})
# 统计字符串中字符的出现次数
my_string = "hello world"
counter = Counter(my_string)
print(counter)
# 输出:Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, 'w': 1, 'r': 1, 'd': 1,'': 1})
假设我们有一个文本文件,需要统计文件中每个单词出现的次数。可以使用 Counter
来轻松实现:
from collections import Counter
def count_words_in_file(file_path):
word_counter = Counter()
with open(file_path, 'r', encoding='utf-8') as file:
for line in file:
words = line.split()
word_counter.update(words)
return word_counter
file_path = 'shanhai.txt'
word_count = count_words_in_file(file_path)
print(word_count)
OrderedDict
类
在Python 3.6 之前的版本中,普通字典(dict
)的元素顺序是无序的。在遍历字典时,元素的顺序可能会与插入顺序不同;Python 3.6 及以上版本中,dict
的元素顺序是有序的。
而 OrderedDict
是一个有序的字典,它会记住元素插入的顺序。在需要保持元素插入顺序的场景中,OrderedDict
非常有用,比如实现一个按照添加顺序处理任务的队列。
示例代码
from collections import OrderedDict
# 创建一个普通字典
regular_dict = {}
regular_dict['c'] = '橙子'
regular_dict['a'] = '苹果'
regular_dict['b'] = '香蕉'
# 创建一个有序字典
ordered_dict = OrderedDict()
ordered_dict['b'] = '香蕉'
ordered_dict['c'] = '橙子'
ordered_dict['a'] = '苹果'
print("普通字典遍历顺序:")
for key, value in regular_dict.items():
print(key, value)
# 输出顺序可能不同
print("有序字典遍历顺序:")
for key, value in ordered_dict.items():
print(key, value)
# 输出顺序与插入顺序一致
defaultdict
defaultdict
是 dict
的子类,它会在访问不存在的键时,自动创建一个默认值。这在处理需要预先初始化值的字典时非常方便,避免了每次访问键时都要检查键是否存在的繁琐操作。
示例代码
from collections import defaultdict
# 创建一个默认值为列表的defaultdict
my_dict = defaultdict(list)
my_dict['a'].append(1)
my_dict['a'].append(2)
my_dict['b'].append(3)
print(my_dict)
# 输出:defaultdict(<class 'list'>, {'a': [1, 2], 'b': [3]})
# 创建一个默认值为整数的defaultdict
my_dict = defaultdict(int)
my_dict['a'] += 1
my_dict['b'] += 2
print(my_dict)
# 输出:defaultdict(<class 'int'>, {'a': 1, 'b': 2})
应用案例
假设我们有一个列表,需要将列表中的元素按照某个属性进行分组。可以使用 defaultdict
来实现:
from collections import defaultdict
students = [
{'name': '张三', 'age': 20},
{'name': '李四', 'age': 21},
{'name': '王五', 'age': 20}
]
age_group = defaultdict(list)
for student in students:
age = student['age']
age_group[age].append(student['name'])
for age, names in age_group.items():
print(f"年龄 {age} 的学生有:{names}")
namedtuple
namedtuple
是一个工厂函数,用于创建一个具有命名字段的元组子类。它可以让我们像使用对象属性一样访问元组中的元素,提高代码的可读性。与普通元组相比,namedtuple
更加清晰和易于维护。
示例代码
from collections import namedtuple
# 创建一个名为Point的namedtuple,包含x和y两个字段
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print(p.x)
# 输出:10
print(p.y)
# 输出:20
# 可以像普通元组一样进行解包
x, y = p
print(x, y)
# 输出:10 20
应用案例
在游戏开发中,经常需要表示二维平面上的点。使用 namedtuple
可以让代码更加清晰和易读:
from collections import namedtuple
# 创建一个名为Vector的namedtuple,包含x和y两个字段
Vector = namedtuple('向量', ['x', 'y'])
def add_vectors(v1, v2):
return Vector(v1.x + v2.x, v1.y + v2.y)
v1 = Vector(1, 2)
v2 = Vector(3, 4)
result = add_vectors(v1, v2)
print(result)
# 输出:向量(x=4, y=6)
deque
deque
是一个双端队列,它允许我们在队列的两端进行高效的添加和删除操作。与普通列表相比,deque
在两端操作的时间复杂度为 O(1),而列表在头部插入和删除元素的时间复杂度为 O(n)。因此,deque
在需要频繁在两端进行操作的场景中表现更优。
示例代码
from collections import deque
# 创建一个deque
my_deque = deque([1, 2, 3])
# 在右端添加元素
my_deque.append(4)
print(my_deque)
# 输出:deque([1, 2, 3, 4])
# 在左端添加元素
my_deque.appendleft(0)
print(my_deque)
# 输出:deque([0, 1, 2, 3, 4])
# 从右端删除元素
my_deque.pop()
print(my_deque)
# 输出:deque([0, 1, 2, 3])
# 从左端删除元素
my_deque.popleft()
print(my_deque)
# 输出:deque([1, 2, 3])