• Python-collections模块之defaultdict


    前言:collections. 这个模块提供容器相关的更高性能的数据类型,它们提供比通用容器 dict, list, set 和tuple更强大的功能。

    namedtuple

    namedtuple 是 元组(tuple)类型的子类,所以本质上它还是一个元组类型,继承了元组所有的的特性,namedtuple 特别之处在于你可以通过名字来访问元组中的元素,类似字典,通过key来访问value。
    对于数据分析或机器学习领域,用好namedtuple 会写出可读性强、易于维护的代码。
    待续...

    defaultdict

    defaultdict 是 dict 类型的子类,正如其名,初始化时,可以给key指定默认值,什么意思呢?直接看代码。
    如果是普通的dict对象,访问一个不存在的key时,会报错:

    dict1 = dict()
    print(dict1['a'])
    """
    Traceback (most recent call last):
      File "D:/Projects/test/t1.py", line 14, in <module>
        print(dict1['a'])
    KeyError: 'a'
    """
    

    而使用defaultdict,可以给不存在的key给一个默认的初始值,例如:
    默认空列表的dict:

    from collections import defaultdict
    
    res1 = defaultdict(list)
    print(res1['a'])  # []
    print(res1.get('a'))  # []
    print(res1.get('a', 'hello world 1'))  # []
    

    默认给一个0的dict:

    from collections import defaultdict
    
    res2 = defaultdict(int)
    print(res2['a'])  # 0
    print(res2.get('a'))  # 0
    print(res2.get('a', 'hello world 2'))  # 0
    

    defaultdict方法接收的参数是一个可调用对象,可以简单理解为一个函数对象,我们知道python中一切皆对象,int、list本来以上一个函数对象,这里如果想要默认值不是0,而是999,该怎么处理呢?
    使用匿名函数,指定defaultdict默认值:

    from collections import defaultdict
    
    res3 = defaultdict(lambda: 999)
    print(res3['b'])  # 999
    print(res3.get('b'))  # 999
    print(res3.get('b', 0))  # 999
    

    当然也可以使用自定义函数,指定defaultdict默认值:

    from collections import defaultdict
    
    def get_default():
        return 'Hello World !'
    
    res4 = defaultdict(get_default)
    print(res4['b'])  # Hello World !
    print(res4.get('b'))  # Hello World !
    print(res4.get('b', 0))  # Hello World !
    

    关于defaultdict的一些应用场景:
    场景一:我们经常想要将一个列表中的数据进行整合,比如这种:

    from collections import defaultdict
    
    initial_data = [('class1', '张三'), ('class2', '李四'), ('class1', '王五'),
            ('class3', '赵六'), ('class3', '李刚弹'), ('class2', '王大炮'),
            ('class1', '王大锤'), ('class2', '李二狗'), ('class1', '佚名')
            ]
    # ==> 变成:
    finally_data = {
        'class1': ['张三', '王五', '王大锤', '佚名'],
        'class2': ['李四', '王大炮', '李二狗', ],
        'class3': ['赵六', '李刚弹']
    }
    # 如果自己实现的话可能会用for循环依次判断,又或者使用到setdefault方法也可以
    # 这里如果使用defaultdict方法算是一种比较优雅的解决吧:
    res5 = defaultdict(list)
    for k, v in initial_data:
        res5[k].append(v)
    
    print(res5 == finally_data)  # True
    

    附:使用setdefault也可以优雅的解决,条条大路通罗马,这就是我理解的python!

    res6 = {}
    for k, v in initial_data:
        res6.setdefault(k, []).append(v)
    
    print(res6 == finally_data)  # True
    
  • 相关阅读:
    修复 XE8 for Android 方向传感器 headingX,Y,Z 不会动的问题
    修复 XE8 for Android 分享图片到 Gmail 权限不足的问题
    Firemonkey 载入 Style 皮肤 (*.fsf 二进制文件) 速度测试
    调整 FMX Android 文字显示「锯齿」效果
    [原创工具] ListView 调色盘 (Free)
    有关Linux的可执行程序
    Android 下配置一个 /dev/fb0 节点出来
    Android下运行Linux可执行程序
    数据库的范式
    rk3128 适配 USB 摄像头
  • 原文地址:https://www.cnblogs.com/suguangti/p/13150567.html
Copyright © 2020-2023  润新知