Python3之内建模块collections
collections是python内建的一个集合模块,提供了许多有用的集合类。
namedtuple
我们知道tuple可以表示不可变集合,例如,一个点的二维坐标可以表示成
1 | >>> p = ( 1 , 2 ) |
但是,看到(1, 2)
,很难看出这个tuple
是用来表示一个坐标的。
定义一个class又小题大做了,这时,namedtuple
就派上了用场:
1 2 3 4 5 6 7 | >>> from collections import namedtuple >>> Point = namedtuple( 'Point' ,[ 'x' , 'y' ]) >>> p = Point( 1 , 2 ) >>> p.x 1 >>> p.y 2 |
namedtuple
是一个函数,它用来创建一个自定义的tuple
对象,并且规定了tuple
元素的个数,并可以用属性而不是索引来引用tuple
的某个元素。
这样一来,我们用namedtuple
可以很方便地定义一种数据类型,它具备tuple的不变性,又可以根据属性来引用,使用十分方便。
可以验证创建的Point
对象是tuple
的一种子类:
1 2 3 4 | >>> isinstance (p,Point) True >>> isinstance (p, tuple ) True |
类似的,如果用坐标和半径表示一个圆,也可以用namedtuple定义
1 2 | >>> Circle = namedtuple( 'Circle' ,[ 'x' , 'y' , 'r' ]) >>> c = Circle( 1 , 2 , 1 ) |
deque
使用list存储数据时,按索引访问元素很快,但插入和删除元素就慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。
deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:
1 2 3 4 5 6 | >>> from collections import deque >>> q = deque([ 'a' , 'b' , 'c' ]) >>> q.append( 'x' ) >>> q.appendleft( 'y' ) >>> q deque([ 'y' , 'a' , 'b' , 'c' , 'x' ]) |
deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常搞笑地往头部添加或者删除元素。
defaultdict
使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict
1 2 3 4 5 6 7 8 9 | >>> from collections import defaultdict >>> dd = defaultdict( lambda : 'N/A' ) >>> dd[ 'key1' ] = 'abc' #key1存储在返回 >>> dd[ 'key1' ] 'abc' #key2不存在返回自定义的默认值 >>> dd[ 'key2' ] 'N/A' |
注意默认值是调用函数返回的,而函数在创建defaultdict
对象时传入。
除了在Key不存在时返回默认值,defaultdict
的其他行为跟dict
是完全一样的。
OrderedDict
使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序
如果要保持Key的顺序,可以使用OrderedDict
1 2 3 4 5 6 7 8 9 | >>> from collections import OrderedDict >>> d = dict ([( 'a' , 1 ),( 'b' , 2 ),( 'c' , 3 )]) #d是无序的 >>> d { 'a' : 1 , 'b' : 2 , 'c' : 3 } >>> od = OrderedDict([( 'a' , 1 ),( 'b' , 2 ),( 'c' , 3 )]) #od是有序的 >>> od OrderedDict([( 'a' , 1 ), ( 'b' , 2 ), ( 'c' , 3 )]) |
注意,OrderedDict的Key会按照插入的顺序排序,不是Key本身排序
1 2 3 4 5 6 7 8 9 | >>> od = OrderedDict() >>> od[ 'z' ] = 1 >>> od[ 'y' ] = 2 >>> od[ 'x' ] = 3 >>> od.keys() odict_keys([ 'z' , 'y' , 'x' ]) #按照插入的Key的顺序返回 >>> list (od.keys()) [ 'z' , 'y' , 'x' ] |
ChinaMap
ChainMap
可以把一组dict
串起来并组成一个逻辑上的dict
。ChainMap
本身也是一个dict,但是查找的时候,会按照顺序在内部的dict依次查找。
什么时候使用ChainMap
最合适?举个例子:应用程序往往都需要传入参数,参数可以通过命令行传入,可以通过环境变量传入,还可以有默认参数。我们可以用ChainMap
实现参数的优 先级查找,即先查命令行参数,如果没有传入,再查环境变量,如果没有,就使用默认参数。
下面的代码演示了如何查找user
和color
这两个参数:
use_chinamap.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #!/usr/bin/env python3 # -*- coding: utf-8 -*- from collections import ChainMap import os, argparse defaults = { 'color' : 'red' , 'user' : 'guest' } parser = argparse.ArgumentParser() parser.add_argument( '-u' , '--user' ) parser.add_argument( '-c' , '--color' ) namespace = parser.parse_args() command_line_args = { k: v for k, v in vars (namespace).items() if v } combined = ChainMap(command_line_args, os.environ, defaults) print ( 'color=%s' % combined[ 'color' ]) print ( 'user=%s' % combined[ 'user' ]) |
运行,没有任何参数时,打印默认参数
1 2 3 | #python3 use_chainmap.py color = red user = guest |
当传入命令行参数时,有限使用命令行参数
1 2 3 | python3 use_chainmap.py - u Zhangsan color = red user = Zhangsan |
同时传入命令行参数和环境变量,命令行参数优先级较高
1 2 3 | user = admin color = green python3 use_chainmap.py - u Zhangsan color = green user = Zhangsan |
Counter
Counter是一个简单的计数器,例如,统计字符出现的个数
1 2 3 4 5 6 7 8 | >>> from collections import Counter >>> c = Counter() >>> for ch in 'prohramming' : ... c[ch] = c[ch] + 1 ... >>> >>> c Counter({ 'r' : 2 , 'm' : 2 , 'p' : 1 , 'o' : 1 , 'h' : 1 , 'a' : 1 , 'i' : 1 , 'n' : 1 , 'g' : 1 }) |
Counter
实际上也是dict
的一个子类,上面的结果可以看出,字符'g'
、'm'
、'r'
各出现了两次,其他字符各出现了一次。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!