Python 笔记(02)— 字典创建、更新、键值对不存在时更新(setdefault)、字典并集、差集、按键排序、按值排序、值为列表 defaultdict

1. 字典创建

In [1]: d = {}

In [2]: d
Out[2]: {}

In [3]: d = dict()

In [4]: d
Out[4]: {}

In [5]: dict(a=1,b=2)
Out[5]: {'a': 1, 'b': 2}

In [7]: dict([('a', 1), ('b', 2)])
Out[7]: {'a': 1, 'b': 2}

In [8]: dict(zip(['a', 'b'], [1, 2]))
Out[8]: {'a': 1, 'b': 2}

注意:在 Python3zip 返回的是一个对象,需要用 list 转换为列表。

In [15]: z = zip(['a', 'b'], [1, 2])

In [16]: z
Out[16]: <zip at 0x6c7b1c8>

In [17]: list(z)
Out[17]: [('a', 1), ('b', 2)]

2. 字典更新

In [1]: d = {'a':1, 'b':2}

# 方法 1
In [2]: d.update({'c': 3})

In [3]: d
Out[3]: {'a': 1, 'b': 2, 'c': 3}

# 方法 2
In [4]: d.update([('d', 4)])

In [5]: d
Out[5]: {'a': 1, 'b': 2, 'c': 3, 'd': 4}

# 方法 3
In [6]: d.update([('e', 5)], f=6)

In [7]: d
Out[7]: {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6}

3. 键值对不存在时更新

如果仅当字典中不存在某个键值对时,才插入到字典中;如果存在,不必插入(也就不会修改键值对)。这种场景,使用字典自带方法 setdefault

In [8]: d = {'a':1, 'b':2}

# 更新成功返回更新的 value
In [9]: d.setdefault('c', 3)
Out[9]: 3

In [10]: d
Out[10]: {'a': 1, 'b': 2, 'c': 3}

# 更新不成功返回默认的 value
In [11]: d.setdefault('a', 4)
Out[11]: 1

In [12]: d
Out[12]: {'a': 1, 'b': 2, 'c': 3}

4. 字典并集

In [16]: def merge(d1, d2):
    ...:     return {**d1, **d2}
    ...:     

In [17]: a = {'a':1, 'b':2}

In [18]: b = {'c':3}

In [19]: merge(a, b)
Out[19]: {'a': 1, 'b': 2, 'c': 3}

In [20]: b = {'b':3}

In [21]: merge(a, b)
Out[21]: {'a': 1, 'b': 3}
    
In [48]: m = merge(a, b)
In [49]: m['a'] = 10
Out[49]: a
In [50]:{'a':1, 'b':2}

ab 中有相同的 key 时,会用最后出现的 key-value 代替之前的 key-value

当修改 merge 之后的元素后, a 中的元素并不变。要想改变可以使用 collections 模块中的 ChainMap

In [50]: from collections import ChainMap
In [52]: d1 = {'x': 1, 'y': 2 }

In [53]: d2 = {'y': 3, 'z': 4 }

In [54]: merged = ChainMap(d1, d2)

In [55]: merged
Out[55]: ChainMap({'x': 1, 'y': 2}, {'y': 3, 'z': 4})

In [56]: merged['y'] = 10

In [57]: merged
Out[57]: ChainMap({'x': 1, 'y': 10}, {'y': 3, 'z': 4})

In [59]: d1
Out[59]: {'x': 1, 'y': 10}

In [60]: d2
Out[60]: {'y': 3, 'z': 4}

5. 字典差集

In [22]: def diff(a, b):
    ...:     return dict([(k, v) for k, v in a.items() if k not in b])
    ...:     

In [23]: a = {'a':1, 'b':2}

In [24]: b = {'b':3}

In [25]: diff(a, b)
Out[25]: {'a': 1}

6. 按键排序

In [26]: d = {"d":4, "c":3, "b":2, "a": 1}

In [27]: d
Out[27]: {'d': 4, 'c': 3, 'b': 2, 'a': 1}

In [28]: sorted(d.items(), key=lambda x: x[0])
Out[28]: [('a', 1), ('b', 2), ('c', 3), ('d', 4)]

d.items() 返回元素为 (key, value) 的可迭代类型(Iterable), key 函数的参数 x 便是元素 (key, value) ,所以 x[0] 取到字典的 key 值。

7. 按值排序

In [34]: d = {"d":1, "a":4, "b":3, "c": 2}

In [35]: sorted(d.items(), key=lambda x: x[1])
Out[35]: [('d', 1), ('c', 2), ('b', 3), ('a', 4)]

8. 最大键值对

In [36]: def max_dict(d):
    ...:     if len(d) == 0:
    ...:         return []
    ...:     max_value = max(d.values())
    ...:     return [(key, max_value) for key in d if d[key]==max_value]
    ...:     

In [39]: d = {'a':1, 'b':2, 'c':2}

In [40]: max_dict(d)
Out[40]: [('b', 2), ('c', 2)]

9. 值为列表

常规做法是判断 key 是否在字典中,不在的话给其赋值为列表。

In [61]: d = {}

In [62]: a = ['a', 'b', 'c']

In [63]: for k in a:
    ...:     if k not in d:
    ...:         d[k] = []
    ...:         

In [64]: d
Out[64]: {'a': [], 'b': [], 'c': []}

比较优雅的写法使用 collections 模块的 defaultdict

In [65]: from collections import defaultdict

In [68]: key_lst = [('a', 'aaa'), ('b', 'bbb'), ('c', 'ccc')]
    
In [71]: d = defaultdict(list)

In [72]: d
Out[72]: defaultdict(list, {})

In [73]: for k, v in key_lst:
    ...:     d[k].append(v)
    ...:     

In [74]: d
Out[74]: defaultdict(list, {'a': ['aaa'], 'b': ['bbb'], 'c': ['ccc']})

In [75]: d.keys()
Out[75]: dict_keys(['a', 'b', 'c'])

In [76]: d.values()
Out[76]: dict_values([['aaa'], ['bbb'], ['ccc']])

10. 找出字典前 N 个最大值

找出字典前 n 个最大值,对应的键。导入 Python 内置模块 heapq 中的 nlargest 函数,获取字典中的前 n 个最大值。 key 函数定义按值比较大小:

In [77]: d = {'a': 10, 'b': 8, 'c': 9, 'd': 10}

In [78]: from heapq import nlargest

In [79]: nlargest(2, d, key=lambda k: d[k])
Out[79]: ['a', 'd']
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wohu007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值