python标准库简介(五)collections模块一

1 collections 模块

python 为我们提供了四种基本的容器数据类型 list,tuple,dict,set。在大部分处理集合类型数据的应用场景,这四种数据结构都能轻松胜任。但是在处理大量数据和处理复杂数据元素运算的时候,这四中数据结构明显功能单一,且运算效率较低。python标准库为我们提供了collections包,里面提供很多功能强大的容器类型,熟练掌握这些容器类型,有助于提高我们的代码质量。这里主要介绍如下几种数据结构。

  • namedtuple
  • OrderedDict
  • defaultdict

2 namedtuple

2.1简介

namedtuple是一个函数,创建一个自定义的tuple对象,规定tuple元素个数以及其对应的属性,可以根据属性而不是索引来访问,具有tuple的不变性,又可以根据属性来引用。创建的namedtuple是tuple类型的子类。


In [2]: from collections import namedtuple

In [3]: Point = namedtuple('Ponit',['x','y'])

In [4]: p = Point(1,2)

In [5]: p.x
Out[5]: 1

In [6]: p.y
Out[6]: 2

In [7]: type(p)
Out[7]: __main__.Ponit

In [8]: isinstance(p,tuple)
Out[8]: True


In [9]: p.x=5
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-9-c7ca42e996c7> in <module>()
----> 1 p.x=5

AttributeError: can't set attribute

2.2 自带描述信息

  • 单纯的看一个元组的信息,我们很难看出元组以及元组每一项所表示的含义,采用namedtuple后,相当于给元组增加了文档描述。
  • namedtuple实例没有对象字典,是一个轻量级数据结构,与普通元组相比并不需要更多内存。这使得他们比字典更快。

下面代码清楚的描述了一个圆的信息,circle相比较于circle2就要清楚太多了。

In [11]: Circle = namedtuple('Circle',['point','r'])

In [12]: circle = Circle(p,'5')

In [13]: circle
Out[13]: Circle(point=Ponit(x=1, y=2), r='5')

In [14]: circle.point.x
Out[14]: 1

In [15]: circle.point.y
Out[15]: 2

In [16]: circle.r
Out[16]: '5'

In [17]: circle2 = ((1,2),5)

In [18]: circle2
Out[18]: ((1, 2), 5)

2.3 实用方法

namedtuple是tuple的子类,具有tuple的所有方法

In [23]: p1 = Point(2,3)

In [24]: p2 = Point(3,4)

In [25]: p1+p2
Out[25]: (2, 3, 3, 4)

In [26]: p1.index(0)

In [27]: p1.index(2)
Out[27]: 0

In [29]: p1.count(1)
Out[29]: 0

In [30]: len(p1)
Out[30]: 2

namedtuple提供了其他方法让我么更灵活的使用该数据结构

In [46]: p._asdict()
Out[46]: OrderedDict([('x', 1), ('y', 2)])

In [47]: p._fields
Out[47]: ('x', 'y')

In [49]: p._make([1,2]) #传入可迭代类型
Out[49]: Ponit(x=1, y=2)

In [51]: p._replace(x=1,y=3) # 传入**kwds
Out[51]: Ponit(x=1, y=3)

3 OrderedDict

3.1 简介

python 中的dict是无序的,在对dict做迭代时我们无法确定dict的顺序。

OrderedDict是dict的子类,支持一般的dict方法,它会记录key加入的顺序,从而实现有序字典,这种数据结构具有强大的威力。

In [65]: d = dict([('a',1),('b',2),('c',3)])

In [66]: d
Out[66]: {'a': 1, 'b': 2, 'c': 3}

In [67]: od = OrderedDict([('a',1),('b',2),('c',3)])

In [68]: od
Out[68]: OrderedDict([('a', 1), ('b', 2), ('c', 3)])

In [70]: od = OrderedDict()

In [71]: od['z']=1

In [72]: od['x']=2

In [73]: od['y']=3

In [74]: od
Out[74]: OrderedDict([('z', 1), ('x', 2), ('y', 3)])

In [75]: for i in od:
    ...:     print(i)
    ...:     
z
x
y

OrderedDict会按照其插入的顺序给予键值对以固定的顺序,这样就可以得到“稳定”的迭代对象,并且可以取出固定位置的键值对

In [88]: od
Out[88]: OrderedDict([('z', 1), ('x', 2), ('y', 3)])

In [89]: od.get([x for x in od][2])
Out[89]: 3

3.2根据字典的键或值的特征进行排序

实现灵活排序

In [90]: d = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}

In [91]: OrderedDict(sorted(d.items(), key=lambda t: t[0])) # 按照键排序
Out[91]: OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])

In [92]: OrderedDict(sorted(d.items(), key=lambda t: t[1])) # 按照值排序
Out[92]: OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

In [93]: OrderedDict(sorted(d.items(), key=lambda t: len(t[0]))) # 按照键长度排序
Out[93]: OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])

# tips: sorted函数key变量,是指在对可迭代对象排序的时候,按照可迭代对象的什么特征进行排序

In [101]: a = ['5','40','345','6000']

In [102]: sorted(a #字符串第一个字符
Out[102]: ['345', '40', '5', '6000']

In [103]: sorted(a,key=lambda t:int(t)) #字符窜转化为int型之后
Out[103]: ['5', '40', '345', '6000']

这样就实现了对字典元素的顺序的定义

3.3 OrderedDict 相关方法

根据可迭代对象生成值为None 的有序字典

In [109]: d = OrderedDict.fromkeys('abcde')

In [110]: d
Out[110]: OrderedDict([('a', None), ('b', None), ('c', None), ('d', None), ('e', None)])
In [9]: d.move_to_end('b')

In [10]: d
Out[10]: OrderedDict([('a', None), ('c', None), ('d', None), ('e', None), ('b', None)])

In [11]: d.popitem()
Out[11]: ('b', None)

In [12]: d.popitem()
Out[12]: ('e', None)

In [13]: d
Out[13]: OrderedDict([('a', None), ('c', None), ('d', None)])

4 defaultdict

4.1 简介

默认值字典

python的dict数据类型在取值dict[key]的时候如果没有key会报错,defaultdict通过则避免了这一行为.使用defaultdict,只要你传入一个默认的工厂方法,那么请求一个不存在的key时, 便会调用这个工厂方法使用其结果来作为这个key的默认值。

其原理是在dict基础上实现了_missing_会调用传入的工厂方法 当_getitem_不存在的时候,就会触发,给本来不存在的键赋默认值

工厂方法默认为None,这个时候由于缺少工厂方法,对不存在的建设置默认值就不会生效


In [53]: d = defaultdict()

In [54]: d
Out[54]: defaultdict(None, {})

In [55]: d['a']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-55-4ff0d9af6f7a> in <module>()
----> 1 d['a']

KeyError: 'a'

当传入工厂方法的时候,设置默认值就会生效.

In [56]: d = defaultdict(list)

In [57]: d['a']
Out[57]: []

In [58]: d
Out[58]: defaultdict(list, {'a': []})

In [59]: d.get('a')
Out[59]: []

In [60]: d['a']
Out[60]: []

4.2 实现序列元素的收集

可以利用defaultdict实现序列元素的分类收集


In [34]: members = [
   ...:     # Age, name
   ...:     ['male', 'John'],
   ...:     ['male', 'Jack'],
   ...:     ['female', 'Lily'],
   ...:     ['male', 'Pony'],
   ...:     ['female', 'Lucy'],
   ...: ]

In [35]: result = defaultdict(list)
   ...: for sex, name in members:
   ...:     result[sex].append(name)
   ...:

In [36]: result
Out[36]: defaultdict(list,{'female': ['Lily', 'Lucy'], 'male'['John', 'Jack', 'Pony']}

In [37]: result['male']
Out[37]: ['John', 'Jack', 'Pony']

当不存在key时候就会自动调用list工厂函数,产生一个空的列表,
上面的代码片段就实现了对具有相同信息的序列结构的筛选.使用dict可用如下方式实现.

In [39]: d = {}

In [40]: for sex, name in members:
    ...:     d.setdefault(sex,[]).append(name)
    ...:     

In [41]: d
Out[41]: {'female': ['Lily', 'Lucy'], 'male': ['John', 'Jack', 'Pony']}

带有默认值的字典

In [49]: f = lambda :'chaoge'

In [50]: d = defaultdict(f)

In [51]: d['a']
Out[51]: 'chaoge'

In [52]: d
Out[52]: defaultdict(<function __main__.<lambda>>, {'a': 'chaoge'})
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容