zoukankan      html  css  js  c++  java
  • 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})
  • 相关阅读:
    VS2008编写MFC程序--使用opencv2.4()
    November 02nd, 2017 Week 44th Thursday
    November 01st, 2017 Week 44th Wednesday
    October 31st, 2017 Week 44th Tuesday
    October 30th, 2017 Week 44th Monday
    October 29th, 2017 Week 44th Sunday
    October 28th, 2017 Week 43rd Saturday
    October 27th, 2017 Week 43rd Friday
    October 26th, 2017 Week 43rd Thursday
    October 25th, 2017 Week 43rd Wednesday
  • 原文地址:https://www.cnblogs.com/xiaoli0520/p/13884452.html
Copyright © 2011-2022 走看看