写点什么

说完列表说字典,说完字典说集合,滚雪球学 Python

发布于: 2021 年 03 月 06 日
说完列表说字典,说完字典说集合,滚雪球学 Python

橡皮擦,一个逗趣的互联网高级网虫,新的系列,让我们一起 Be More Pythonic


二、字典与集合那些事儿


字典和集合为何总要放在一起,说来也巧,就是因为它们都用大括号 {} 包裹。


2.1 字典和集合那些基础操作


2.1.1 先说字典


字典是由键值对组成的,键为 Key,值为 Value,标记一下,在 Python3.6 之前字典是无需的,长度大小可变,元素也可以任意的删除和改变,在 Python 3.7 之后,字典有序了。


为了测试字典的无序性,我专门在 Python 线上环境进行了测试,代码如下:


my_dict = {}my_dict["A"] = "A"my_dict["B"] = "B"my_dict["C"] = "C"my_dict["D"] = "D"
for key in my_dict: print(key)
复制代码


运行结果也证明了无序性。

在本地 Python 3.8 版本测试,没有出现乱序的情况。


所以再有人问 Python 里面的字典有没有顺序呀,不要直接回答无序了,这玩意现在有顺序。


字典这种键值对结构,相较于列表与元组更加适合添加元素、删除元素、查找元素等操作。


字典的创建不在细说,滚雪球第一遍学习的时候,已经涉及了,需要注意的是索引键的时候,如果键不存在,会出现 KeyError 错误,该错误属于极其常见错误。


my_dict = {}my_dict["A"] = "A"my_dict["B"] = "B"my_dict["C"] = "C"my_dict["D"] = "D"
print(my_dict["F"])
复制代码


错误提示如下:


Traceback (most recent call last):  File ".\demo.py", line 7, in <module>    print(my_dict["F"])KeyError: 'F'
复制代码


如果你不希望此异常出现,在索引键的时候使用 get(key,default) 函数即可。


print(my_dict.get("F","None"))
复制代码


2.1.2 再聊集合


集合和字典基本结构相同,最大的区别是集合没有键值对,它是一系列无序且唯一的元素组合。

集合不支持索引操作,也就是说下面的代码肯定是会报错的。


my_set = {"A","B","C"}print(my_set[0])
复制代码


异常提示为类型错误:TypeError: 'set' object is not subscriptable


其余重点记忆的就是集合经常用在去重操作上,掌握即可。


2.2 字典与集合的排序


基本操作依旧不在过多解释,需要的可以去第一遍滚雪球学习,这里强调一下排序函数,因为涉及了一些扩展知识点,可以先接触一下,后面对于部分内容还会细讲。


学习之前,你要记住,对集合进行 pop 操作,得到的元素是不确定的,因为集合无序,具体你可以测试如下代码:


my_set = {"A","B","C"}print(my_set.pop())
复制代码


如果希望对字典排序,按照咱们已知的技术,可以这样进行。

以下内容为 Python3.6 版本以下运行结果。

直接使用 sorted 函数即可对字典排序,排序的时候,还可以指定按照键或者值进行排序,例如按照字典值升序排序。


my_dict = {}my_dict["A"] = "4"my_dict["B"] = "3"my_dict["C"] = "2"my_dict["D"] = "1"sorted_dict = sorted(my_dict.items(),key=lambda x:x[1])print(sorted_dict)
复制代码


输出结果如下,得到的结果是按照字典的值进行排序的,这里需要注意的是 lambda 匿名函数在后续的课程将逐步展开


[('D', '1'), ('C', '2'), ('B', '3'), ('A', '4')]
复制代码


集合排序无特别说明,直接使用 sorted 函数即可。


2.3 字典与集合的效率问题


字典与集合的效率问题,主要对比的对象是列表,假设现在有一堆学号和体重的数据,咱们需要判断出不同体重数的学生人数。

需求描述如下:

有 4 个学生,按照学号排序形成的元组为 (1,90)(2,90)(3,60)(4,100),最终的结果输出 3(存在三个不同的体重)

按照需求编写代码如下:

列表写法


def find_unique_weight(students):    # 声明一个统计列表    unique_list = []    # 循环所有学生数据    for id, weight in students:        # 如果体重没有在统计列表中        if weight not in unique_list:            # 新增体重数据            unique_list.append(weight)    # 计算列表长度    ret = len(unique_list)    return ret
students = [ (1, 90), (2, 90), (3, 60), (4, 100)]print(find_unique_weight(students))
复制代码


接下来上述代码修改为集合写法



def find_unique_weight(students): # 声明一个统计集合 unique_set = set() # 循环所有学生数据 for id, weight in students: # 集合会自动过滤重复数据 unique_set.add(weight) # 计算集合长度 ret = len(unique_set) return ret
复制代码


代码写完之后,并未发现有太大的差异,但是如果把数据扩大到更大的两集,例如上万数据。

以下代码时间计算函数应用的是 time.perf_counter() 该函数第一次调用时,从计算机系统里随机选一个时间点 A,计算其距离当前时间点 B1 有多少秒。当第二次调用该函数时,默认从第一次调用的时间点 A 算起,距离当前时间点 B2 有多少秒。两个函数取差,即实现从时间点 B1 到 B2 的计时功能,首先结合列表计算的函数,运行下述代码


import timeid = [x for x in range(1, 10000)]# 体重数据为了计算,也只能从 1 到 10000 了weight = [x for x in range(1, 10000)]students = list(zip(id, weight))
start_time = time.perf_counter()# 调用列表计算函数find_unique_weight(students)end_time = time.perf_counter()print("运算时间为:{}".format(end_time - start_time))
复制代码


运行时间为 1.7326523,每台电脑运行速度不一致,具体看差异。

修改上述代码运行到集合编写的函数上,最终得到的结果为 0.0030606,可以看到在 10000 条数据的量级下就已经产生了如此大的差异,如果数量级在进行上升,差异会再次加大,所以你了解到该用什么内容了吗?


2.4 这篇博客的总结


这篇博客,我们对字典与集合相关的知识进行了补充,有一个知识橡皮擦依旧进行了略过,就是字典与集合的存储原理,具体会涉及到哈希表结构相关知识,这部分对初级应用影响不大,所以暂时略过,对于字典与集合来说,如果你在编写程序中需要高效查找数据、去重数据,建议及时的把二者应用起来。


相关阅读


  1. Python 爬虫 100 例教程,超棒的爬虫教程,立即订阅吧

  2. Python 爬虫小课,精彩 9 讲




今天是持续写作的第 <font color="red">93</font> / 100 天。

如果你想跟博主建立亲密关系,可以关注同名公众号 <font color="red">梦想橡皮擦</font>,近距离接触一个逗趣的互联网高级网虫。

博主 ID:梦想橡皮擦,希望大家<font color="red">点赞</font>、<font color="red">评论</font>、<font color="red">收藏</font>。


发布于: 2021 年 03 月 06 日阅读数: 33
用户头像

爬虫 100 例作者,蓝桥签约作者,博客专家 2021.02.06 加入

6 年产品经理+教学经验,3 年互联网项目管理经验; 互联网资深爱好者; 沉迷各种技术无法自拔,导致年龄被困在 25 岁; CSDN 爬虫 100 例作者。 个人公众号“梦想橡皮擦”。

评论

发布
暂无评论
说完列表说字典,说完字典说集合,滚雪球学 Python