Python字典和集合的底层原来是这么玩的

 更新时间:2026年06月02日 08:20:08   作者:To_OC  
在Python算法竞赛中,集合(set)和字典(dict)是两个高频使用的内置数据结构,二者分工明确,这篇文章主要介绍了Python字典和集合底层的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

昨天写 Python 小脚本,脑子一抽想把列表当成字典的 key 存数据,敲完回车控制台直接甩来一个报错,当时我人都傻了,盯着屏幕看了半天,愣是没明白为啥字符串能当 key,列表就不行。

截图就是当时控制台报的 unhashable type: 'list',就是这行破代码,逼得我把字典、哈希表、可变不可变对象全啃了一遍。

说实话,我之前对字典的理解就停留在 “存键值对的容器”,啥底层原理、使用限制一概不知,这次踩坑后才算真的吃透,趁热乎把我的思考过程分享给大家。

先搞懂:字典为啥比列表快到飞起?

最开始我存「名字 - 成绩」,用的是最笨的原始方法:

# 两个列表,下标一一对应,纯纯笨方法
names = ['周杰伦', '蔡徐坤', '周星驰']
score = [100, 2.5, 100]

# 想查蔡徐坤的分数?得遍历列表找下标,数据多了直接慢死

这就是列表的硬伤:查找、插入的速度会跟着元素变多越来越慢。

然后 Python 的字典就登场了,我给它打个最贴切的比方:字典就是书本最前面的索引目录。你想找某一页内容,不用从头翻到尾,看目录直接定位页码;字典底层是哈希表,key 通过哈希算法算出一个唯一的索引,直接找到 value 的存储地址,所以查找速度是 O (1),不管多少数据,都是秒查。

这才是字典的正确打开方式:

    # 字python典:key-value键值对
    d = {'周杰伦': 100, '蔡徐坤': 2.5, '周星驰': 100}
    # 直接查找,瞬间出结果
    print(d['蔡徐坤'])  # 2.5

日常用字典的增删改查,我也把踩过的小坑整理好了:

    # 1. 修改已有的key
    d['周杰伦'] = 88
    print(d['周杰伦'])  # 88

    # 2. 千万别直接访问不存在的key!会直接报错
    # d['ikun']  # KeyError,血的教训

    # 3. 安全访问:用in判断 / get方法
    print('ikun' in d)  # False
    print(d.get('ikun'))  # None,不报错
    print(d.get('ikun', -1))  # 可以指定默认值,太香了
    print(d.get('蔡徐坤', -1))  # 2.5

    # 4. 删除key
    d.pop('蔡徐坤')

核心大坑:为啥列表绝对不能当字典的 key?

绕回最开始的报错,我第一反应是:“Python 歧视列表?凭啥字符串就行?”后来翻了哈希表的设计规则,才恍然大悟:字典的 key 必须是可哈希的,也就是不可变类型。

哈希算法的硬性要求:key 必须固定不变!如果 key 是可变的(比如列表),你改一下列表内容,哈希计算的结果就变了,字典直接找不到 value 的位置,整个哈希表就乱套了。

字符串、数字、元组是不可变的,所以能当 key;列表、字典是可变的,Python 直接禁止它们当字典的 key。

顺便记一下字典的优缺点,别把它当万能药:

  • 优点:查找、插入极快,不随元素增多变慢
  • 缺点:占用内存大,典型的空间换时间

秒懂 Set:就是个没有 value 的字典

搞懂字典后,看 Set 集合简直是降维打击!Set 和字典的底层原理一模一样,唯一区别:Set 只存 key,不存 value,而且 key 不能重复,天生自带去重功能。

直接上可运行的 demo:

    # 两种创建set的方式
    s = {1, 2, 3}
    # 列表转set,自动去重
    s = set([1,2,3,2,5])
    print(s)  # {1,2,3,5}

    # 增删元素
    s.add(4)
    s.remove(4)

    # 集合运算:交集、并集,处理数据超好用
    s1 = {1, 2, 3}
    s2 = {2, 3, 4}
    print(s1 & s2)  # 交集 {2,3}
    print(s1 | s2)  # 并集 {1,2,3,4}

终极迷惑:可变对象 vs 不可变对象

本来以为字典搞定就收工了,结果又被列表sort和字符串replace坑了一把,这俩的效果完全不一样!

    # 列表:可变对象
    a = ['c', 'b', 'a']
    print(a.sort())  # None!坑!sort直接修改原列表,不返回新对象
    print(a)  # ['a', 'b', 'c']

    # 字符串:不可变对象
    str_obj = 'abc'
    # replace不会改原字符串,只会返回新的字符串!
    print(str_obj.replace('a', 'A'))  # Abc
    print(str_obj)  # abc 原对象纹丝不动

现在彻底理清了:

  • 可变对象(list、dict、set):调用方法会直接修改自身
  • 不可变对象(str、数字、元组):调用方法只会返回新对象,原数据永远不变

写在最后

这次从一个报错啃完所有知识点,脑子里就刻下了三个核心:

  1. 字典底层是哈希表,靠 key 哈希定位 value,key 必须是不可变类型
  2. 可变 / 不可变对象是核心,别再搞混sort和replace的效果
  3. Set 就是精简版字典,专门用来去重、做集合运算

也别神话字典,小数据量、不需要快速查找的场景,用列表更省内存。

这次踩坑爬坑的过程还挺有意思的。

到此这篇关于Python字典和集合底层的文章就介绍到这了,更多相关Python字典和集合底层内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Notepad 轻量级文本编辑器的安装及基本使用

    Notepad 轻量级文本编辑器的安装及基本使用

    notepad–是一个国产跨平台、轻量级的文本编辑器,是替换notepad++的一种选择,notepad特点支持Window/Mac/Linux操作系统平台,支持其他notepad竞品的常用功能,这篇文章给大家介绍Notepad 轻量级文本编辑器的安装及基本使用,感兴趣的朋友一起看看吧
    2024-01-01
  • Python实现监控一个程序的运行情况

    Python实现监控一个程序的运行情况

    这篇文章主要为大家介绍了Python如何实现监控一个程序的运行情况,然后视情况将进程杀死并重启,文中的示例代码简洁易懂,需要的可以参考一下
    2023-05-05
  • 基于Python3读写INI配置文件过程解析

    基于Python3读写INI配置文件过程解析

    这篇文章主要介绍了基于Python3读写INI配置文件过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • Python可视化Matplotlib散点图scatter()用法详解

    Python可视化Matplotlib散点图scatter()用法详解

    这篇文章主要介绍了Python可视化中Matplotlib散点图scatter()的用法详解,文中附含详细示例代码,有需要得朋友可以借鉴参考下,希望能够有所帮助
    2021-09-09
  • 利用Django-environ如何区分不同环境

    利用Django-environ如何区分不同环境

    这篇文章主要给大家介绍了关于利用Django-environ如何区分不同环境的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用django具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-08-08
  • 用python做一个搜索引擎(Pylucene)的实例代码

    用python做一个搜索引擎(Pylucene)的实例代码

    下面小编就为大家带来一篇用python做一个搜索引擎(Pylucene)的实例代码。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • Django1.9 加载通过ImageField上传的图片方法

    Django1.9 加载通过ImageField上传的图片方法

    今天小编就为大家分享一篇Django1.9 加载通过ImageField上传的图片方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • python基础之reverse和reversed函数的介绍及使用

    python基础之reverse和reversed函数的介绍及使用

    我们在整理资料的时候,有的时候过于混乱难以整理,这时我们不妨可以对它先进行一个排序,这样可以方便我们浏览,查询,有利于我们整理资料,下面这篇文章主要给大家介绍了关于python基础之reverse和reversed函数的介绍及使用,需要的朋友可以参考下
    2022-12-12
  • Python中的if、else、elif语句用法简明讲解

    Python中的if、else、elif语句用法简明讲解

    这篇文章主要介绍了Python中的if、else、elif语句的用法讲解,条件判断语句是程序中流程控制的基础办法之一,需要的朋友可以参考下
    2016-03-03
  • 基于python实现操作git过程代码解析

    基于python实现操作git过程代码解析

    这篇文章主要介绍了基于python实现操作git过程代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07

最新评论