Python中使用defaultdict简化字典键值对操作的便捷方法
1.字典键-值对中,值元素的便捷创建增减

主要是将 collections 里的 defaultdict 加以利用。
普通复杂过程:
pairs 包含了('a', 1)这个元素,同时也包含了('a', 2)这个元素,还包含了('b', 2)这个元素。
d = {}
for key, value in pairs:
if key not in d:
d[key] = [] #指定值为list类型
d[key].append(value)
或
d = {} #普通字典
定义一个名为 d 的字典,设置其默认值为键为 'a',值为一个空列表。然后将数字 1 添加到这个列表中。
定义一个名为 d 的字典,若字典中不存在键 'a',则设置默认值为一个空列表,然后将 2 添加到该列表中。
d 中设置默认值为键 'b' 对应的值为一个空列表,然后将 4 添加到这个列表中
当我们使用普通的字典时,能够创建一个空字典,即 dict = {}。添加元素时,只需使用 dict[element] = value 的方式。在调用元素时,也是通过 dict[element] 来进行。但要注意的是,必须确保 element 在字典中,如果 element 不在字典里,进行调用就会报错。
利用defaultdict就没这些问题,且精简:
defaultdict 会以一个工厂函数作为参数,其构造方式如下:
使用 defaultdict 创建了一个名为 dict 的对象,其中的 factory_function 用于指定默认值的工厂函数。
这个 factory_function 可以是 list、set、str 等。它有两个作用:其一,当调用的 key 不存在时,会返回工厂函数的默认值,例如 list 对应的是[ ],str 对应的是空字符串,set 对应的是 set( ),int 对应的是 0;其二,能够对值进行操作,即调用相应类的函数。
从 collections 库中导入 defaultdict 类。
d = defaultdict(list)
for key, value in pairs:
d[key].append(value)
d = defaultdict(list)
d['a'].append(1)
d['a'].append(2)
d['b'].append(4)
d = defaultdict(set)
d['a'].add(1)
d['a'].add(2)
d['b'].add(4)
2.创建带顺序的字典
使用有序字典(OrderedDict)。 有序字典是一种数据结构。 它可以按照插入的顺序保存键值对。 与普通字典不同,它保留了元素的插入顺序。 在 Python 中,有序字典非常有用。 例如,当需要按照特定顺序处理数据时。 它可以提供便利。 可以使用 from collections 导入有序字典。 这样就可以在代码中使用有序字典了。
d = OrderedDict()
d['foo'] = 1
d['bar'] = 2
d['spam'] = 3
d['grok'] = 4
输出 "foo" 以及 "1";输出 "bar" 以及 "2";输出 "spam" 以及 "3";输出 "grok" 以及 "4"
for key in d:
print(key, d[key])
后续若修改已插入的键值,字典的顺序不会改变。顺序字典的内存开销比较大,要是数据量很大(例如 100,000 条以上),就考虑使用其他结构来保存数据。
顺序字典的一个应用实例,json串构造:
>>> import json
>>> json.dumps(d)
3.字典排序相关
prices = {
'ACME': 45.23,
'AAPL': 612.78,
'IBM': 205.55,
'HPQ': 37.20,
'FB': 10.75
}
# 通常:
返回“AAPL”,它是价格中的最小值。
返回的是“IBM”,它是价格中的最大值。
返回的是 prices 中值的最小值,其值为 10.75
返回了 612.78,它是 prices.values()中的最大值
# 高级一点:
在 prices 中找到值最小的键,这个键对应的就是 prices 中值最小的元素,而这个键就是 'FB' 。
在 prices 中通过 key=lambda k: prices[k] 找到最大值对应的键,这个键为 'AAPL'
在 prices 中找到值最小的元素,通过 key=lambda k: prices[k] 来确定最小元素,然后将这个最小元素的值赋给 min_value,即 min_value 等于 prices 中值最小的那个元素的值。
使用 lambda 函数作为 key 对 prices 进行排序,排序后的结果为 ['FB', 'HPQ', 'ACME', 'IBM', 'AAPL']
要获取较全的键值信息都比较繁琐,以上这些情况都如此。不过,可以将其转化成(值,键)的形式来进行排序。
找到 prices 中的值和键进行组合,然后取其中值的最小值,将这个最小值和对应的键组成一个元组,最后取这个元组中的值作为 min_price
min_price 的值是 10.75 且来自于 'FB'
首先获取 prices 的值和键,然后将它们进行 zip 操作,接着找出其中的最大值,最后将这个最大值赋值给 max_price 。
max_price 的值为(612.78, 'AAPL')。
prices_sorted 是通过对 zip(prices.values(), prices.keys()) 进行排序得到的。首先获取 prices 的值组成的列表,然后获取 prices 的键组成的列表,接着将这两个列表用 zip 函数组合在一起,最后对组合后的结果进行排序,排序后的结果赋值给 prices_sorted 。
prices_sorted 包含 (10.75, 'FB') 和 (37.2, 'HPQ') 这两组数据,其中一个价格为 10.75 对应的是 'FB',另一个价格为 37.2 对应的是 'HPQ'
坐标 (45.23, 'ACME'),坐标 (205.55, 'IBM')
# (612.78, 'AAPL')]
注意zip生成一个迭代器,只能用一次
另外,还可以将字典转换为列表,即 li = list(prices.items()),然后使用【Python 练习册】中 heapq 的应用的方法来进行排序。
4.两个字典间找异同--三种构造方式对比
dict.keys()是一个 dict_keys 对象,具体称作 keys-view 对象。dict.items 是一个 dict_items 对象,具体称作 items-view 对象。之所以称之为 view,是因为随着 dict 的变化,这些 view 也会自动改变。keys-view 对象支持常规 set 操作,像求差集等。
a = {
'x': 1,
'y': 2,
'z': 3
}
b = {
'w': 10,
'x': 11,
'y': 2
}
# 找相同键
a 的键与 b 的键进行交集操作 # 结果为 { 'x', 'y' }
# 找在a中不在b中的键
a 的键集合减去 b 的键集合,结果为 {'z'}
# 找相同元素
a.items() 与 b.items() 的交集 # { ('y', 2) }
# 移除特定键构建新字典
c 等于这样一个字典:其中的键是 a 字典中的键,并且这些键不在 {'z', 'w'} 这个集合中,对应的值是 a 中这些键所对应的值。
c 包含 {'x': 1, 'y': 2} ;c 中 'x' 的值为 1 ;c 中 'y' 的值为 2 。
#也可如下构造--最快,没有a[]的查询过程
p2 等于一个字典推导式的结果,这个推导式是遍历 a 中的每一个键值对(key, value),然后只保留那些键(key)不在 {'z', 'w'} 中的键值对,将这些符合条件的键值对组成一个新的字典。
#也可如下构造--最慢
使用字典推导式创建一个新的字典 p1,其中包含原字典 a 中所有键值对,但键不在 {'z', 'w'} 中的那些。即遍历原字典 a 的键值对,将键不在指定集合 {'z', 'w'} 中的键值对添加到新字典 p1 中。
因为 value 值可以不唯一。