美文网首页程序员
python标准库简介(五)collections模块一

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

作者: 躺好别动 | 来源:发表于2018-04-14 21:25 被阅读0次

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'})

相关文章

网友评论

    本文标题:python标准库简介(五)collections模块一

    本文链接:https://www.haomeiwen.com/subject/ugickftx.html