社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

二十九、深入Python中的 collections 模块

Python开发 • 4 年前 • 438 次点击  
👇👇关注后回复 “进群” ,拉你进程序员交流群👇👇

作者丨小sen

来源丨Python之王


「@Author:Runsen」

collections模块是一个不用不知道,一用就上瘾的模块。这里主要介绍OrderedDict类、defaultdict类、Counter类、namedtuple类和deque类。

    collections

    collections的常用类型有:

    • 计数器(Counter)

    • 双向队列(deque)

    • 默认字典(defaultdict)

    • 有序字典(OrderedDict)

    • 可命名元组(namedtuple)

    Counter

    计数器(counter)以字典的形式返回序列中各个字符出现的次数,值为key,次数为value

    Counter是对字典类型的补充,用于追踪值得出现次数 。

    import collections

    counter = collections.Counter("My name is Runsen")
    print(counter)

    输出如下

    Counter({' ': 3, 'n': 3, 'e': 2, 's': 2, 'M': 1, 'y': 1, 'a': 1, 'm': 1, 'i': 1, 'R': 1, 'u': 1})

    取得元素重复次数的值

    print(counter[' '])
    3

    elements()取得计数器中的所有元素。

    注:此处非所有元素集合,而是包含所有元素集合的迭代器.

    counter = collections.Counter('abcabcabcdabcdef'
    print(counter)
    # 输出如下
    Counter({'a'4'b'4'c'4'd'2'e'1'f'1})

    print(counter.elements())
    # 输出如下
    0x0000025B1477BF98>

    print(list(counter.elements()))
    # 输出如下
    ['a''a''a''a''b''b''b''b''c''c''c''c''d''d''e''f']

    将Counter按照value从大到小排列,获取前N个元素,需要使用函数most_common

    # most_common(N)数量从大到小排列,获取前N个元素 
    print(counter.most_common(3))
    # 输出如下
    [('a'4), ('b'4), ('c'4)]

    sorted将Counter中的key进行排序,返回的是所有key的列表

    # sorted()列出所有不同的元素并排序 
    print(sorted(counter))

    # 输出如下
    ['a''b''c''d''e''f']

    将Counter转换成字符串,字符串的join方法可以解决。注意不是原来的模样。

    # 转换成字符串 
    print(''.join(counter.elements()))
    # aaaabbbbccccddef
    print(''.join(list(counter.elements())))

    update()更新计数器,其实在原本的counter更新计数器,如果原来没有,则新建key,如果有value则加一

    # update()更新计数器,
    d = collections.Counter('a'
    counter.update(d) 
    print(counter) 
    # 输出如下
    Counter({'a'5'b'4'c'4'd'2'e'1'f'1})

    update()更新计数器,那么subtract()相减计数器的values,即原来的计数器中的每一个元素的数量减去后添加的元素的数量

    counter.subtract('abdabcabcg'
    print(counter)

    # 输出如下
    Counter({'a'2'c'2'b'1'd'1'e'1'f'1 'g'-1})

    deque

    deque支持从任意一端增加和删除元素。更为常用的两种结构,就是栈和队列。

    deque的常见操作

    #定义一个空的双向队列
    d = collections.deque()

    #从右端增加元素
    d.extend("Runsen"
    d.append("Maoli")
    d.append("Python")
    d.append("king")

    #从左端增加元素
    d.appendleft('left')
    print(d)
    # 输出如下 (注意:extend和append的区别)
    deque(['left''R''u''n''s''e''n''Maoli''Python''king'])

    # reverse()反转队列 
    print(d.reverse())
    d.reverse()
    print(d)
    # 输出如下
    None
    deque(['king''Python''Maoli''n''e''s''n''u''R''left'])


    d.reverse()
    d.extend(['qq','ww','ee']) 
    print(d) 
    # deque(['left', 'R', 'u', 'n', 's', 'e', 'n', 'Maoli', 'Python', 'king', 'qq', 'ww', 'ee'])


    # count()计数 
    print(d.count('R'))
    # 输出如下
    1

    # clear()清空队列 
    d.clear() 
    print(d) 
    # 输出如下
    deque([])

    # index()取得元素下标 
    print(d.index('Maoli'))
    # 输出如下
    7

    # insert()指定位置插入元素 
    d.insert(1,'Runsen'
    print(d) 
    # deque(['left', 'Runsen',R', 'u', 'n', 's', 'e', 'n', 'Maoli', 'Python', 'king', 'qq', 'ww', 'ee'])

    OrderedDict

    使用dict时要保持Key的顺序,可以用OrderedDict。

    from collections import OrderedDict 
    dic = OrderedDict() 
    dic['k1'] = 'v1' 
    dic['k2'] = 'v2' 
    dic['k3'] = 'v3' 
    print(dic) 
    # 输出如下
    OrderedDict([('k1''v1'), ('k2''v2'), ('k3''v3')])

    # 字典所有的键 
    print(dic.keys())
    # 输出如下

    odict_keys(['k1''k2''k3'])
        
    # 字典所有值 
    print(dic.values())
    # 输出如下
    odict_values(['v1''v2''v3'])
        
    # items() 方法以列表返回可遍历的(键, 值) 元组数组 
    print(dic.items())

    # 输出如下
    odict_items([('k1''v1'), ('k2''v2'), ('k3''v3')])
        

    #pop()方法,删除指定的键值 
    dic.pop('k1')  
    print(dic) 
    # 输出如下
    OrderedDict([('k2''v2'), ('k3''v3')])


    #popitem()方法,默认删除字典最后一个元素 
    dic.popitem() 
    print(dic) 
    # 输出如下
    OrderedDict([('k2''v2')])

    # update()更新字典 
    dic.update({'k1':'v1111','k10' :'v10'}) 
    print(dic) 
    # 输出如下
    OrderedDict([('k2''v2'), ('k1''v1111'), ('k10''v10')])

    OrderedDict和字典操作完全相同,区别在于OrderedDict的Key会按照插入的顺序排列,不是Key本身排序

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

    defaultdict

    在使用字典的时候, 如果在使用不存在的key的时候发生KeyError这样的一个报错, 这时候就该defaultdict登场了。

    defaultdict接受一个工厂函数作为参数来构造:dict =defaultdict( factory_function)

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

    from collections import defaultdict

    dict1 = defaultdict(int)
    dict2 = defaultdict(set)
    dict3 = defaultdict(str)
    dict4 = defaultdict(list)
    dict1[2] ='two'

    print(dict1[1])
    print(dict2[1])
    print(dict3[1])
    print(dict4[1])

    # 输出如下
    0
    set()

    []

    defaultdict类接受类型名称作为初始化函数的参数,这样使得默认值的取值更加灵活。

    s = 'mynameisrunsen'
    d = collections.defaultdict(int)
    for k in s:
        d[k] += 1
    print(d)

    # 输出如下
    defaultdict(<class 'int'>, {'m': 2'y'1'n'3'a'1'e'2'i'1's'2'r'1'u'1})

    练习有如下值集合 [11,22,33,44,55,66,77,88,99,99]

    下面将所有大于 55的值保存至字典的第一个key中,将小于 55 的值保存至第二个key的值中。

    下面通过defaultdict默认字典对列表进行划分。

    all_list = [11,22,33,44,55,66,77,88,99]
    dic = collections.defaultdict(list)
    for i in all_list:
        if i > 55:
            dic['k1'].append(i)
        else:
            dic['k2'].append(i)
    print(dic)
    # 输出如下
    defaultdict('list'>, {'k2': [11, 22, 33, 44, 55], 'k1': [66, 77, 88, 99]})

    也可以使用字典,具体代码如下。

    all_list = [11,22,33,44,55,66,77,88,99]
    dic = {}
    for  i in all_list:
        if i > 55:
            if "k1" in dic.keys():
                dic['k1'].append(i)
            else:
                dic['k1'] = [i,]
        else:
            if "k2" in dic.keys():
                dic['k2'].append(i)
            else:
                dic['k2'] = [i,]
    print(dic)
    # 输出如下
    {'k2': [11, 22, 33, 44, 55], 'k1': [66, 77, 88, 99]}

    namedtuple

    namedtuple是用来创建一个自定义的tuple对象,并且规定了tuple元素的个数,并可以用属性而不是索引来引用tuple的某个元素。

    使用命名元组的步骤:

    # 将元组封装为一个类,可以通过字段名(属性名)来访问元组中的值
    # 支持元组的所有操作
    from collections import namedtuple
    # 1、定义一个类
    Runsen = namedtuple('Runsen', ['name','sex','age'])
    # 2、创建对象
    runsen = Runsen("Runsen""帅男"21)
    # 3、获取命名元组的值
    print(runsen[1])    # 支持元组的索引取值  
    print(runsen[-2:])  # 支持切片
    print(runsen.name)  # 支持通过字段名来取值 
    # _fields,获取命名元组的所有属性名
    print(runsen._fields)
    # _asdict方法,将元组转化为字典
    print(runsen._asdict())

    # 输出如下

    帅男
    ('帅男'21)
    Runsen
    ('name''sex''age')
    OrderedDict([('name''Runsen'), ('sex''帅男'), ('age'21)])

    Reference

    [1]

    传送门~: https://github.com/MaoliRUNsen/runsenlearnpy100


    -End-

    最近有一些小伙伴,让我帮忙找一些 面试题 资料,于是我翻遍了收藏的 5T 资料后,汇总整理出来,可以说是程序员面试必备!所有资料都整理到网盘了,欢迎下载!

    点击👆卡片,关注后回复【面试题】即可获取

    在看点这里好文分享给更多人↓↓

    Python社区是高质量的Python/Django开发社区
    本文地址:http://www.python88.com/topic/114252
     
    438 次点击