addict使用简介

背景

如果我们需要定义一个嵌套层次比较多的字典,我们通常会这么写,如:

body = {
    'query': {
        'filtered': {
            'query': {
                'match': {'description': 'addictive'}
            },
            'filter': {
                'term': {'created_by': 'Mats'}
            }
        }
    }
}

但有了addict模块,使用addict的字典是一个乐趣。addict 继承自字典,但在访问和设置其值方面更加灵活

相关文档及安装

pip install addict

addict模块的使用

对比参看字典操作

定义和初始化

# 例1:
d = {
    'query': {
        'filtered': {
            'query': {
                'match': {'description': 'addictive'}
            },
            'filter': {
                'term': {'created_by': 'Mats'}
            }
        }
    }
}

print(d, type(d))

from addict import Dict

d1 = Dict()
d1.query.filtered.query.match.description = "addictive"
d1.query.filtered.filter.term.created_by = "Mats"
print(d1, type(d1))

d2 = Dict()
d2.query.filtered.query.match = {'description': 'addictive'}
d2.query.filtered.filter.term = {'created_by': 'Mats'}
print(d2, type(d2))
---------------------------输出结果----------------------
{'query': {'filtered': {'query': {'match': {'description': 'addictive'}}, 'filter': {'term': {'created_by': 'Mats'}}}}} <class 'dict'>
{'query': {'filtered': {'query': {'match': {'description': 'addictive'}}, 'filter': {'term': {'created_by': 'Mats'}}}}} <class 'addict.addict.Dict'>
{'query': {'filtered': {'query': {'match': {'description': 'addictive'}}, 'filter': {'term': {'created_by': 'Mats'}}}}} <class 'addict.addict.Dict'>
  • d = Dict(iterable),可迭代对象的元素必须是二元结构
# 例2:
from addict import Dict

d1 = dict([('a', 1), ['b', 2], ['c', [1, 2]], {1, 2}])
print(d1, type(d1))
print('=='*20)
d2 = Dict([('a', 1), ['b', 2], ['c', [1, 2]], {1, 2}])
print(d2, type(d2))
-----------------------输出结果------------------------
{'a': 1, 'b': 2, 'c': [1, 2], 1: 2} <class 'dict'>
========================================
{'a': 1, 'b': 2, 'c': [1, 2], 1: 2} <class 'addict.addict.Dict'>

元素访问

from addict import Dict

d = Dict([('a', 1), ['b', {'c': [1, 2]}], ['d', [1, 2]], {1, 2}])
print(d)  # {'a': 1, 'b': {'c': [1, 2]}, 'd': [1, 2], 1: 2}

print(d.b.c)
print(d.b['c'])
print(d.b.c[0])
# print(d.1) # SyntaxError: invalid syntax
print(d[1])

# 不存在的key
print(d.e, type(d.e))
print(d['e'], type(d['e']))  # 丢失的键返回一个空的Dict
---------------------输出结果---------------------
{'a': 1, 'b': {'c': [1, 2]}, 'd': [1, 2], 1: 2}
[1, 2]
[1, 2]
1
2
{} <class 'addict.addict.Dict'>
{} <class 'addict.addict.Dict'>

元素增加和修改

from addict import Dict

d = Dict([('a', 1), ['b', {'c': [1, 2]}], ['d', [1, 2]], {1, 2}])
print(d)  # {'a': 1, 'b': {'c': [1, 2]}, 'd': [1, 2], 1: 2}

d.a = 2
d.b['c'] = 'jerry'
d[1] = 3
print(d)

# 不存在key
d[3] = 'hello'
d.e.f = 2
print(d)

# d.keys = 2  # AttributeError: 'Dict' object attribute 'keys' is read-only 不可以通过这种方式覆盖Dict的属性如keys, items
d['keys'] = 1
print(d)
----------------输出结果----------
{'a': 1, 'b': {'c': [1, 2]}, 'd': [1, 2], 1: 2}
{'a': 2, 'b': {'c': 'jerry'}, 'd': [1, 2], 1: 3}
{'a': 2, 'b': {'c': 'jerry'}, 'd': [1, 2], 1: 3, 3: 'hello', 'e': {'f': 2}}
{'a': 2, 'b': {'c': 'jerry'}, 'd': [1, 2], 1: 3, 3: 'hello', 'e': {'f': 2}, 'keys': 1}

更新

注:跟字典dict的update方法有区别,addict 的更新会递归并实际更新嵌套的字典

from addict import Dict

d = {'a': {'b': 3}}
d.update({'a': {'c': 4}})
print(d)

d = Dict({'a': {'b': 3}})
d.update({'a': {'c': 4}})
print(d)
----------输出结果------------
{'a': {'c': 4}}
{'a': {'b': 3, 'c': 4}}

转化为普通字典

from addict import Dict

d = Dict([('a', 1), ['b', {'c': [1, 2]}], ['d', [1, 2]], {1, 2}])
print(d, type(d))  # {'a': 1, 'b': {'c': [1, 2]}, 'd': [1, 2], 1: 2}

d1 = d.to_dict()
print(d1, type(d1))
---------输出结果------------
{'a': 1, 'b': {'c': [1, 2]}, 'd': [1, 2], 1: 2} <class 'addict.addict.Dict'>
{'a': 1, 'b': {'c': [1, 2]}, 'd': [1, 2], 1: 2} <class 'dict'>

转化为普通字典后则可做字典的一些其他操作了,如删除等

计数

from addict import Dict

data = [
    {'born': 1980, 'gender': 'M', 'eyes': 'green'},
    {'born': 1980, 'gender': 'F', 'eyes': 'green'},
    {'born': 1980, 'gender': 'M', 'eyes': 'blue'},
    {'born': 1980, 'gender': 'M', 'eyes': 'green'},
    {'born': 1980, 'gender': 'M', 'eyes': 'green'},
    {'born': 1980, 'gender': 'F', 'eyes': 'blue'},
    {'born': 1981, 'gender': 'M', 'eyes': 'blue'},
    {'born': 1981, 'gender': 'F', 'eyes': 'green'},
    {'born': 1981, 'gender': 'M', 'eyes': 'blue'},
    {'born': 1981, 'gender': 'F', 'eyes': 'blue'},
    {'born': 1981, 'gender': 'M', 'eyes': 'green'},
    {'born': 1981, 'gender': 'F', 'eyes': 'blue'}
]

counter = Dict()

for row in data:
    born = row['born']
    gender = row['gender']
    eyes = row['eyes']
    # print(born, gender, eyes)

    counter[born][gender][eyes] += 1

print(counter)
--------------------输出结果-------------------
{1980: {'M': {'green': 3, 'blue': 1}, 'F': {'green': 1, 'blue': 1}}, 1981: {'M': {'blue': 2, 'green': 1}, 'F': {'green': 1, 'blue': 2}}}