Python collections模块之defaultdict详解


collections模块常用类型有:

  • 默认字典(defaultdict
    dict的子类,可以调用提供默认值的函数
    请点击defaultdict

  • 双向队列(deque
    类似于list的容器,可以快速的在队列头部和尾部添加、删除元素
    请点击deque

  • 计数器(Counter
    dict的子类,计算可hash的对象
    请点击Counter

  • 有序字典(OrderedDict)
    dict的子类,可以记住元素的添加顺序

  • 可命名元组(namedtuple)
    可以创建包含名称的tuple

Python中通过Key访问字典,当Key不存在时,会引发‘KeyError’异常。为了避免这种情况的发生,可以使用collections类中的defaultdict()方法来为字典提供默认值

defaultdict是内置数据类型dict的一个子类,基本功能与dict一样,只是重写了一个方法missing(key)和增加了一个可写的对象变量default_factory

语法格式:

collections.defaultdict([default_factory[,]])

missing(key)

  • 如果default_factory属性为None,就报出以key作为遍历的KeyError异常;
  • 如果default_factory不为None,就会向给定的key提供一个默认值,这个值插入到词典中,并返回;
  • 如果调用default_factory报出异常,这个异常在传播时不会改变;
  • 这个方法是当要求的key不存在时,dict类中的getitem()方法所调用,无论它返回或者报出什么,最终返回或报出给getitem();
  • 只有getitem()才能调用missing(),这意味着,如果get()起作用,如普通的词典,将会返回None作为默认值,而不是使用default_factory;

default_factory, 这个属性用于missing()方法,使用构造器中的第一个参数初始化;

使用list作为default_factory,很容易将一个key-value的序列转换为list字典;

列表字典

from collections import defaultdict

s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
d = defaultdict(list)
for k, v in s:
    d[k].append(v)
a = d.items()
print(a)
b = sorted(d.items())
print(b)

"""
结果:
dict_items([('yellow', [1, 3]), ('blue', [2, 4]), ('red', [1])])
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
"""

当字典中没有的键第一次出现时,default_factory自动为其返回一个空列表,list.append()会将值添加进新列表;再次遇到相同的键时,list.append()将其它值再添加进该列表。
这种方法比使用dict.setdefault()更为便捷,dict.setdefault()也可以实现相同的功能。

e = {}
for k, v in s:
    e.setdefault(k, []).append(v)
a = e.items()
print(a)

b = sorted(e.items())
print(b)

"""
结果:
dict_items([('yellow', [1, 3]), ('blue', [2, 4]), ('red', [1])])
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
"""

计数

设置default_factory为int,使得defaultdict可以用于计数

from collections import defaultdict

s = "chlzdjlongdong"
d = defaultdict(int)
for k in s:
    d[k] += 1
a = d.items()
print(a)

b = sorted(d.items())
print(b)
"""
结果:
dict_items([('c', 1), ('h', 1), ('l', 2), ('z', 1), ('d', 2), ('j', 1), ('o', 2), ('n', 2), ('g', 2)])
[('c', 1), ('d', 2), ('g', 2), ('h', 1), ('j', 1), ('l', 2), ('n', 2), ('o', 2), ('z', 1)]
"""

字符串中的字母第一次出现时,字典中没有该字母,default_factory函数调用int()为其提供一个默认值0,加法操作将计算出每个字母出现的次数。

from collections import defaultdict

s = "chlzdjlongdong"
d = defaultdict(int)
for k in s:
    d[k] += 1
a = d.items()
print(a)
b = sorted(d.items())
print(b)

"""
结果:
dict_items([('c', 1), ('h', 1), ('l', 2), ('z', 1), ('d', 2), ('j', 1), ('o', 2), ('n', 2), ('g', 2)])
[('c', 1), ('d', 2), ('g', 2), ('h', 1), ('j', 1), ('l', 2), ('n', 2), ('o', 2), ('z', 1)]
"""

集合字典

将default_factory设置为set,使得defaultdict可以建立一个集合字典

from collections import defaultdict

s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]
d = defaultdict(set)
for k, v in s:
    d[k].add(v)
a = d.items()
print(a)
b = sorted(d.items())
print(b)
"""
结果:
dict_items([('red', {1, 3}), ('blue', {2, 4})])
[('blue', {2, 4}), ('red', {1, 3})]
"""
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐