深度解析python中的数据结构和算法(二)

接着上一篇的分享我们继续往下看

目录

1.字典中的键映射多个值

2.字典排序

3.字典的运算

4.查找两个字典的相同点

5.删除序列相同的元素并保持顺序

6.结束语

1.字典中的键映射多个值

问题:字典怎么实现一个键对应多个值?

思路:我们都知道python中的字典的key是唯一的,但是value不是唯一的,这也就意味着。可以有多个value映射在我们的key中,如果想要一个键映射多个值,那么我们就需要将多个值放在另外的容器中,比如放在列表、集合、元组里面。

代码实现:

d = {
    'a':[1,2,3],
    'b':(5,6,7),
    'c':{7,8,9}
}

注意:选择什么样的数据结构做我们的value取决于当前实际需求,主要熟悉这几个数据结构的特性即可有效快速选择。例如:列表的有序,元组的无序,集合的去重等等。

扩展:我们也可以使用collections模块中的defaultdict来创建我们的字典,且好处就是defaultdict会自动初始化每个key刚开始对应的值,所以我们只需要往容器里面添加后面的值就可以了。

代码实现:

常规映射方法:

d = {
    'a':[1,2,3],
    'b':(5,6,7),
    'c':{7,8,9}
}
d1 = {}
for key,value in d.items():
    if key not in d1:
        d1[key] = []
    d1[key].append(value)
print(d1)
"""以上结果是:{'a': [[1, 2, 3]], 'b': [(5, 6, 7)], 'c': [{8, 9, 7}]}"""

使用defaultdict映射方法:

from collections import defaultdict
d = {
    'a':[1,2,3],
    'b':(5,6,7),
    'c':{7,8,9}
}
d1 = defaultdict(list)
for key,value in d.items():
    d1[key].append(value)
print(d1)
"""以上结果是:{'a': [[1, 2, 3]], 'b': [(5, 6, 7)], 'c': [{8, 9, 7}]}"""

可以发现用defaultdict其实就是省略了初始化定义key对应的值的过程,巧妙运用有利于调高代码简洁性

2.字典排序

问题:创建一个字典,并且在迭代或者序列化的时候能够控制元素的顺序

思路:为了能控制一个字典中元素的顺序,我们可以使用collection模块中OrderedDict类,在迭代操作的时候会保持元素插入的顺序。

代码实现:

from collections import OrderedDict

def collect_dict():
    d = OrderedDict()
    d['a'] = 1
    d['b'] = 2
    d['c'] = 3
    for key in d:
        print(key,d[key])

if __name__ == '__main__':
    collect_dict()

扩展:当我们想要精确控制以json编码后的顺序,就可以使用Ordereddict来解决问题。

代码扩充:

from collections import OrderedDict
import json
def collect_dict():
    d = OrderedDict()
    d['a'] = 1
    d['b'] = 2
    d['c'] = 3
    for key in d:
        print(key,d[key])
    print(json.dumps(d))

if __name__ == '__main__':
    collect_dict()

3.字典的运算

问题:我们经常会遇到再一个字典当中求最大值、最小值、排序等操作。这也是对字典数据结构考察最多的问题,代码中经常会用到。

思路:为了对字典进行运算操作,我们通常会用zip函数将键和值反转一下,因为很多运算操作都是在比较值的大小从而对整个字典进行运算的。

代码实现:

score = {
    '语文':115,
    '数学':136,
    '英语':107,
    '物理':87,
    '化学':75,
    '生物':76,
}
new_score = zip(score.values(),score.keys())
print(dict(new_score)) # {115: '语文', 136: '数学', 107: '英语', 87: '物理', 75: '化学', 76: '生物'}

当我们拿到了分数,是不是就很好对其进行运算了呢?如下:

score = {
    '语文':115,
    '数学':136,
    '英语':107,
    '物理':87,
    '化学':75,
    '生物':76,
}
new_score = zip(score.values(),score.keys())
print(dict(new_score)) # {115: '语文', 136: '数学', 107: '英语', 87: '物理', 75: '化学', 76: '生物'}
print(min(new_score))  # (75, '化学')
print(max(new_score))  # (136, '数学')
print(sorted(new_score))  # [(75, '化学'), (76, '生物'), (87, '物理'), (107, '英语'), (115, '语文'), (136, '数学')]

总结:通过以上计算我们可以发现,只要是计算的话仅仅是作用与key上的。所以我们用到了zip去转换。

扩展:不用zip也可以对字典进行运算,这里就可以用到我们的匿名函数lambda。

代码实现:

score = {
    '语文':115,
    '数学':136,
    '英语':107,
    '物理':87,
    '化学':75,
    '生物':76,
}
new_score1 = sorted(score.keys())
print(new_score1)  # ['化学', '数学', '物理', '生物', '英语', '语文']
new_score2 = sorted(score.values())
print(new_score2)  # [75, 76, 87, 107, 115, 136]
new_score = sorted(score.items(),key=lambda k:k[1])
print(new_score)  # [('化学', 75), ('生物', 76), ('物理', 87), ('英语', 107), ('语文', 115), ('数学', 136)]

除了keys没有办法比较意外,其他的都排序了。

4.查找两个字典的相同点

问题:怎么在两个字典中寻找相同点,比如字典的键或者字典的值

思路:为了寻找两个字典的相同点,可以用keys,或者values,items用与或非的逻辑运算符确定

代码实现:

d1 = {
    'x':1,
    'y':2,
    'c':11
}
d2 = {
    'x':3,
    'y':2,
    'z':11
}

print(d1.keys() & d2.keys())  # {'y', 'x'}
print(d1.keys() - d2.keys())  # {'c'}
print(d1.items() & d2.items())  # {('y', 2)}

5.删除序列相同的元素并保持顺序

问题:如何在一个序列上面保持元素顺序的同时消除重复元素

思路:python中我们可以利用集合的特性或者生成器来解决这个问题

代码实现:

a = [1,2,5,6,1,2,6,7,9]
new_list  = []
for i in a:
    if i not in new_list:
        new_list.append(i)
    else:
        pass
print(new_list)

思考:如果不是哈希结构的数据,怎么解决呢?

给定数据:

d = [{'x':1,'y':2},{'h':3,'d':4},{'x':1,'y':2},{'m':5,'n':6}]

欢迎大家探讨留言哦

6.结束语

今天是分享python中的数据结构和算法的第二天,后续还有几篇,有兴趣的朋友可以和我一起学习,可能有分享的不对的地方还请指正,专业术语上可能也有缺漏,创作不易,还望多多支持。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

戒酒的李白-Lisage

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

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

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

打赏作者

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

抵扣说明:

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

余额充值