Python 核心技术与实战
景霄
Facebook 资深工程师
114324 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 47 讲
开篇词 (1讲)
Python 核心技术与实战
15
15
1.0x
00:00/00:00
登录|注册

14 | 答疑(一):列表和元组的内部实现是怎样的?

可以在函数内部修改
UnboundLocalError异常
可变对象的全局变量
不可变对象的全局变量
多态的概念
保证except中异常赋予的变量不再被用到
异常赋予变量在except block结束时被删除
提高空间利用率
Indices和Entries两个array
元素越来越多导致稀疏
重新分配更大的内存
分配了内存但没有元素的位置
entries列表
根据元素键的哈希值计算插入位置
over-allocate的array
缓存内部的free list
优化的array
tupleobject.c
tupleobject.h
allocated存储空间大小
ob_item指针列表
over-allocate的array
listobject.c
listobject.h
函数内部修改全局变量
Python自己判断类型的多态和子类继承的多态Polymorphism
"NameError"异常
新哈希表结构
哈希表空间利用率
哈希表存储形式
旧哈希表示意图
tuple的具体结构
元组的源码
list的具体结构
Python 3.7 的list源码
关于多态和全局变量的修改
有关异常的困扰
为什么在旧哈希表中,元素会越来越稀疏?
答疑(一):列表和元组的内部实现是怎样的?

该思维导图由 AI 生成,仅供参考

你好,我是景霄。
转眼间,专栏上线已经一个月了,而我们也在不知不觉中完成了第一大章基础篇的学习。我非常高兴看到很多同学一直在坚持积极地学习,并且留下了很多高质量的留言,值得我们互相思考交流。也有一些同学反复推敲,指出了文章中一些表达不严谨或是不当的地方,我也表示十分感谢。
大部分留言,我都在相对应的文章中回复过了。而一些手机上不方便回复,或是很有价值很典型的问题,我专门摘录了出来,作为今天的答疑内容,集中回复。

问题一:列表和元组的内部实现

第一个问题,是胡峣同学提出的,有关列表(list)和元组(tuple)的内部实现,想知道里边是 linked list 或 array,还是把 array linked 一下这样的方式?
关于这个问题,我们可以分别从源码来看。
先来看 Python 3.7 的 list 源码。你可以先自己阅读下面两个链接里的内容。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Python中的列表和元组的内部实现是如何的?旧哈希表为什么会变得越来越稀疏?对于异常的困扰以及多态和全局变量的修改问题又是如何解决的呢?本文通过回答读者提出的问题,深入解析了这些Python编程中的技术问题。文章首先从Python 3.7的源码出发,详细解释了列表和元组的内部实现原理,以及旧哈希表和新哈希表的结构差异。同时,对于异常处理中的变量赋值和多态的概念也进行了深入的解释和分析。此外,文章还解答了全局变量的修改问题,阐述了不可变对象和可变对象在函数内部的不同表现。通过这些问题的解答,读者可以更深入地了解Python编程中的一些技术细节,为他们的编程实践提供了有益的参考和指导。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Python 核心技术与实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(24)

  • 最新
  • 精选
  • 夜路破晓
    个人认知:感觉会看源码的人都很牛!我也想成人牛人,那么问题来了: 如何学习看源码?

    作者回复: 根据需求,首先了解每一个block,每一个函数的大概意思,然后看下去,不懂的多去google一下,看多了你的水平自然就提高了

    2019-06-10
    5
    75
  • 阿卡牛
    over-allocate是什么意思

    作者回复: 会分配比实际元素多的空间,比如一个array实际有5个元素,但是如果是over-allocate的array,可能会分配10个元素的空间大小

    2019-06-10
    2
    18
  • SCAR
    对于问题四的2而言,是因为python是动态语言,不要求声明变量,但是约定在函数体中赋值的变量是局部变量,所以需要理解的是“赋值”这个动作,不管是常规的完整赋值或是增强赋值,只有函数体内初次出现赋值就认为定义了局部变量。这样你就很好理解了,老师的例子中x+=1,出现了赋值,那么这个x就是局部变量了,而x+=1这个增强赋值的第二步会去找函数体内x的引用,于是就出现了找不到的错误。如果把x+=1改成print(x),则是打印出1,因为函数体没出现赋值,那么这个x是最上面赋值的x,它是全局的。
    2019-06-10
    8
    63
  • yshan
    重新查了下理解了下多态:多态就是多种形态。 有了继承,才有多态了。 继承了就具有父类的方法,然后子类就能够覆写父类方法,子类就能够调用该方法实现自己的需求。
    2019-06-10
    10
  • 小侠龙旋风
    1.细看了over-allocated分配空间大小的增长规律,4 4 8 9 10 11 12...不知道这样设计的缘由。 2."当tuple的大小不超过20时,Python会把它缓存在内部的一个free list中。"这句话突然让我想起了小整数池。 小整数池的概念:Python提前建立好范围在[-5, 256]的整数对象,且不会被垃圾回收。无论这个整数处于LEGB中的哪个位置,所有位于这个范围内的整数使用的都是同一个对象。 主要目的是为了避免频繁申请和销毁小整数的内存空间,提高程序的运行效率。 3.说一下我所理解的新哈希表的设计思想: indice下标,entry入口。用下标去寻找对应元素。 维护一个数据量较小的结构,去访问一个数据量较大的结构。 同理,也被运用于函数: 函数的本质是在堆Heap中放置的对象; 函数名的本质是放在栈Stack中的地址,指向堆中放置的对象。 以上,思维比较发散,说得不对还望指出。
    2019-06-13
    9
  • 18646333118
    辛苦老师,希望能用更通俗的语言或者例子来帮助我们这帮菜鸟理解哈哈,有的时候感觉老师明白,但是编辑成文字总是差一点 哈
    2019-06-11
    5
  • xavier
    对于我这种野生程序员来说,收获颇多。每一篇都是从基础开始,然后循序渐进。感谢老师!
    2019-07-11
    3
  • Geek_d848f7
    老师,原谅我还是不太理解这2点吧 1. 列表分配大小时,遵循下面模式:0、4、8…,我看源代码的确这样,但是怎么算都对不上,求指导; 2. 哈希的存储怎么知道是如图形式呢?尤其是无元素位置,这个位置为啥要分配呢?
    2019-06-10
    3
  • 隰有荷
    不太明白为什么新哈希表的结构是 Indices None | index | None | None | index | None | Entries 这种形式? None和index的排列有什么规则吗?为什么会有None?
    2019-08-23
    2
    2
  • 瞳梦
    list的append()并不是一个赋值操作,不会去定义新的变量。而是会根据LEGB规则去寻找list这个变量。
    2019-07-08
    2
收起评论
显示
设置
留言
24
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部