python collections模块

collections模块

在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。

1.namedtuple: 生成可以使用名字来访问元素内容的tuple

2.deque: 双端队列,可以快速的从另外一侧追加和推出对象

3.Counter: 计数器,主要用来计数

4.OrderedDict: 有序字典

5.defaultdict: 带有默认值的字典

namedtuple(具名元组)

因为元组的局限性:不能为元组内部的数据进行命名,所以往往我们并不知道一个元组所要表达的意义,所以在这里引入了 collections.namedtuple 这个工厂函数,来构造一个带字段名的元组。具名元组的实例和普通元组消耗的内存一样多,因为字段名都被存在对应的类里面。这个类跟普通的对象实例比起来也要小一些,因为 Python 不会用 __dict__ 来存放这些实例的属性。

namedtuple 对象的定义如以下格式:

collections.namedtuple(typename, field_names, verbose=False, rename=False)

返回一个具名元组子类 typename,其中参数的意义如下:

  • typename:元组名称
  • field_names: 元组中元素的名称
  • rename: 如果元素名称中含有 python 的关键字,则必须设置为 rename=True
  • verbose: 默认就好

下面来看看声明一个具名元组及其实例化的方法:

from collections import namedtuple

# 两种方法来给 namedtuple 定义方法名
#User = namedtuple('User', ['name', 'age', 'id'])
User = namedtuple('User', 'name age id')
user = User('tester', '22', '464643123')

print(user)

#输出结果
User(name='tester', age='22', id='464643123')
View Code

collections.namedtuple('User', 'name age id') 创建一个具名元组,需要两个参数,一个是类名,另一个是类的各个字段名。后者可以是有多个字符串组成的可迭代对象,或者是有空格分隔开的字段名组成的字符串(比如本示例)。具名元组可以通过字段名或者位置来获取一个字段的信息。

具名元组的特有属性:

  • 类属性 _fields:包含这个类所有字段名的元组
  • 类方法 _make(iterable):接受一个可迭代对象来生产这个类的实例
  • 实例方法 _asdict():把具名元组以 collections.OrdereDict 的形式返回,可以利用它来把元组里的信息友好的展示出来
from collections import namedtuple

# 定义一个namedtuple类型User,并包含name,sex和age属性。
User = namedtuple('User', ['name', 'sex', 'age'])

# 创建一个User对象
user = User(name='Runoob', sex='male', age=12)

# 获取所有字段名
print( user._fields )

# 也可以通过一个list来创建一个User对象,这里注意需要使用"_make"方法
user = User._make(['Runoob', 'male', 12])

print( user )
# User(name='user1', sex='male', age=12)

# 获取用户的属性
print( user.name )
print( user.sex )
print( user.age )

# 修改对象属性,注意要使用"_replace"方法
user = user._replace(age=22)
print( user )
# User(name='user1', sex='male', age=21)

# 将User对象转换成字典,注意要使用"_asdict"
print( user._asdict() )
# OrderedDict([('name', 'Runoob'), ('sex', 'male'), ('age', 22)])

#以上实例输出结果为:
('name', 'sex', 'age')
User(name='Runoob', sex='male', age=12)
Runoob
male
12
User(name='Runoob', sex='male', age=22)
OrderedDict([('name', 'Runoob'), ('sex', 'male'), ('age', 22)])
具名元祖的特有属性

 deque(双向列表)

使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。

deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:

1.创建deque序列:

from collections import deque

d=deque()

2.deque提供了类似list的操作方法:

d=deque()

d.append(3)

d.append(8)

d.append(1)

那么此时d=deque([3,8,1]),len(d)=3,d[0]=3,d[-1]=1

3.两端都使用pop:

d=deque(‘12345’)

那么d=deque(['1', '2', '3', '4', '5'])

d.pop()抛出的是’5’,d.leftpop()抛出的是’1’,可见默认pop()抛出的是最后一个元素。

#4.限制deque的长度

d=deque(maxlen=20)

for i in range(30):

    d.append(str(i))

#此时d的值为d=deque(['10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29'], maxlen=20),可见当限制长度的deque增加超过限制数的项时,另一边的项会自动删除。

#5.添加list各项到deque中:

d=deque([1,2,3,4,5])

d.extend([0])

#那么此时d=deque([1,2,3,4,5,0])

d.extendleft([6,7,8])

#此时d=deque([8, 7, 6, 1, 2, 3, 4, 5, 0])
deque 列表操作

 

OrderedDict(有序字典)

使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。

如果要保持Key的顺序,可以用OrderedDict

from collections import OrderedDict
d = dict([('a', 1), ('b', 2), ('c', 3)])
print(d) # dict的Key是无序的
#输出 {'a': 1, 'c': 3, 'b': 2}

od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
print(od) # OrderedDict的Key是有序的
#输出 OrderedDict([('a', 1), ('b', 2), ('c', 3)])
OrderedDict

 注意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序:

od = OrderedDict()
od['z'] = 1
od['y'] = 2
od['x'] = 3

print(od.keys()) # 按照插入的Key的顺序返回
#['z', 'y', 'x']
View Code

 

defaultdict (默认字典)

当我使用普通的字典时,用法一般是dict={},添加元素的只需要dict[element] =value即,调用的时候也是如此,dict[element] = xxx,但前提是element字典里,如果不在字典里就会报错,如:
bag = ['apple', 'orange', 'cherry', 'apple','apple', 'cherry', 'blueberry']
count = {}
for fruit in bag:
    count[fruit] += 1

错误:
KeyError: 'apple'
KeyError 异常

defaultdict类避免KeyError异常:

import collections
bag = ['apple', 'orange', 'cherry', 'apple','apple', 'cherry', 'blueberry']
count = collections.defaultdict(int)
for fruit in bag:
    count[fruit] += 1

输出:
defaultdict(<class 'int'>, {'apple': 3, 'orange': 1, 'cherry': 2, 'blueberry': 1})
defaultdict避免异常

如何使用defaultdict

defaultdict接受一个工厂函数作为参数,如下来构造:

dict =defaultdict( factory_function)

这个factory_function可以是list、set、str等等,作用是当key不存在时,返回的是工厂函数的默认值,比如list对应[ ],str对应的是空字符串,set对应set( ),int对应0

from collections import defaultdict
def zero():
    return 0
dic = defaultdict(zero)
dic['bbb']
print(dic)

#输出:
#defaultdict(<function zero at 0x000001754EB4B488>, {'bbb': 0})
函数作为参数

Counter(计数器)

Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。Counter类和其他语言的bags或multisets很相似。

c = Counter('abcdeabcdabcaba')
print c
输出:Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})
posted @ 2020-10-27 13:58  小李探花0520  阅读(107)  评论(0编辑  收藏  举报