Python标准库collections详解:namedtuple、defaultdict、Counter与deque实战
本文深入解析Python标准库collections中的核心容器类型。通过namedtuple实现可读性更强的元组,利用defaultdict避免KeyError并简化字典操作,借助Counter高效统计元素频次,以及使用deque实现高性能的双端队列操作。涵盖各类型的创建、常用方法及实际应用场景,帮助开发者减少重复代码,提升编程效率。
写在之前
Python内置了多种标准数据结构,如列表、元组和字典等。此外,其标准库还提供了额外的数据结构支持,允许开发者基于这些基础类型构建更复杂或特定的数据结构。
Python内置的collections模块提供了丰富的容器数据类型。本文将重点介绍其中几种常用类型,掌握它们有助于避免重复造轮子,简化代码开发过程。
namedtuple
元组是一种不可变的序列数据结构。namedtuple(命名元组)与标准元组类似,同样不可修改其内部数据。两者的主要区别在于访问方式:标准元组依赖整数索引,而namedtuple提供了更具语义化的访问方式。
对于普通元组,必须通过整数索引来获取数据:
>>> people = ('Rocky', 'python')
>>> print(people[0])
Rocky
namedtuple将元组转化为适用于简单任务的容器。它允许开发者通过字段名而非整数索引来访问数据,这种类似字典的访问方式使得代码更加直观易读。
>>> from collections import namedtuple
>>> people = namedtuple('people', 'name age like')
>>> Rocky = people(name = 'rocky', age = 23, like = 'python')
>>> print(Rocky)
people(name='rocky', age=23, like='python')
>>> print(Rocky.name)
rocky
创建namedtuple需要指定两个参数:元组名称和字段名称。例如,定义名为people的namedtuple,包含name、age和like三个字段。这种方式不仅提高了代码的可读性,还便于维护,因为可以直接通过字段名(如Rocky.name)访问数据,无需记忆索引位置。
需要注意的是,尽管使用体验类似可变对象,namedtuple本质上仍是元组,因此其属性值一旦创建便不可更改。
既然namedtuple支持类似字典的访问,它也可以转换为字典格式。具体转换方法如下:
>>> from collections import namedtuple
>>> people = namedtuple('people', 'name age like')
>>> Rocky = people(name = 'rocky', age = 23, like = 'python')
>>> print(Rocky._asdict())
OrderedDict([('name', 'rocky'), ('age', 23), ('like', 'python')])
defaultdict
在使用普通字典时,如果访问不存在的键会引发KeyError异常。defaultdict通过提供默认工厂函数解决了这一问题,使得开发者无需预先检查键是否存在即可直接操作数据。
from collections import defaultdict
languages = (
('rocky', 'python'),
('snow', 'c'),
('leey', 'java'),
('rocky', 'c++'),
('leey', 'c#')
)
favourite = defaultdict(list)
for name, language in languages:
favourite[name].append(language)
print(favourite)
运行结果如下所示:
defaultdict(<type 'list'>, {'leey': ['java', 'c#'], 'rocky': ['python', 'c++'], 'snow': ['c']})
回顾普通字典中键不存在时触发KeyError的情况:
my_dict = {}
my_dict['name']['like'] = 'python'
输出如下:
KeyError: 'name'
defaultdict通过巧妙的机制规避了上述问题。具体实现如下:
import collections language = lambda : collections.defaultdict(language) my_dict = language() my_dict['name']['like'] = 'python'
运行正常后,可以使用json.dumps查看my_dict的内容:
import json print(json.dumps(my_dict))
运行结果如下:
{"name": {"like": "python"}}
Counter
Counter是一个计数器类,用于统计可哈希对象的出现频率。例如,它可以用来统计每个人擅长的编程语言数量。
from collections import Counter
languages = (
('rocky', 'python'),
('snow', 'c'),
('leey', 'java'),
('rocky', 'c++'),
('leey', 'c#')
)
cnt = Counter(name for name, language in languages)
print(cnt)
运行结果如下所示:
Counter({'leey': 2, 'rocky': 2, 'snow': 1})
此外,Counter还可用于统计文件内容,例如:
from collections import Counter
with open('test.txt', 'rb') as f: line_cnt = Counter(f)
print(line_cnt)
deque
deque(双端队列)允许在队列的首尾两端高效地添加或删除元素。
使用deque前,需从collections模块导入。创建deque对象后,其用法与列表类似,但提供了更多针对两端操作的方法,具体如下:
from collections import deque deq = deque() deq.append(1) deq.append(2) deq.append(3) print(deq) print(len(deq)) print(deq[0]) print(deq[-1])
输出结果如下:
deque([1, 2, 3]) 3 1 3
我们可以从队列的两端移除数据:
from collections import deque
deq = deque(range(5))
print('len(deq) == {}'.format(len(deq)))
deq.popleft()
deq.pop()
print(deq)
输出的结果如下所示:
len(deq) == 5 deq == deque([1, 2, 3])
deque支持限制最大长度。当新元素加入导致超出限制时,另一端的元素会被自动移除。具体操作如下:
from collections import deque deq = deque(maxlen=3) deq.append(1) deq.append(2) deq.append(3) print(deq) deq.append(4) print (deq)
输出的结果如下:
deque([1, 2, 3], maxlen=3) deque([2, 3, 4], maxlen=3)
当元素数量超过maxlen限制时,最左侧的数据将从队列中自动弹出。
此外,还可以从任意一端向双端队列扩展数据:
from collections import deque deq = deque([1,2,3]) deq.extendleft([0]) deq.extend([4,5,6]) print(deq)
输出的结果如下所示:
deque([0, 1, 2, 3, 4, 5, 6])
以上就是详解Python 中的容器 collections的详细内容,更多关于python collections的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













