• 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})
  • 相关阅读:
    【POJ 1655】Balancing Act
    【POJ 2631】 Roads in the North
    【洛谷 1002】 过河卒
    【洛谷 3178】树上操作
    【洛谷 1060】开心的金明
    【洛谷 2709】小B的询问
    【洛谷 1972】HH的项链
    JavaSpark-sparkSQL
    java8下spark-streaming结合kafka编程(spark 2.3 kafka 0.10)
    Kafka 使用Java实现数据的生产和消费demo
  • 原文地址:https://www.cnblogs.com/xiaoli0520/p/13884452.html
Copyright © 2020-2023  润新知