python常见的数据类型有:字符串,布尔类型,整数,浮点数,数字,日期,列表,元祖,字典。相信前面6个大家都非常的熟悉,但是对于python的列表,元祖,字典我有时候一直在想其内部的实现是怎么样子的,它们就像一个“黑盒子”一样,下面记录一下对于“列表 list”理解过程:

其实,在最开始我一直以为python的列表是通过链表实现的,直到一天,应该说是误打误撞,当我通过交互模式创建一个列表的时候,然后通过id()函数打印出列表中每个元素的地址时,我发现它们的地址是连续的,然后推测python的列表list不是我们传统意义上面的列表(虽然这个推测应该算是误打误撞吧,真实的原因不是这个,这个每个元素地址连续也是因为正好凑巧而已,但是却引起了我的进一步探索和思考),也就是说不是通过链表实现的(因为如果是链表的话其元素地址肯定是不连续的),然后我就猜测这种内存地址连续的情况,python的列表应该是通过数组的形式进行存储实现的。

通过查看python文档:https://wiki.python.org/moin/TimeComplexity,其中记录了这么一句话:Internally, a list is represented as an array;这也进一步验证了我推测的结果。然后查看python的源码:

typedef struct {
PyObject_VAR_HEAD
PyObject **ob_item;
Py_ssize_t allocated;
} PyListObject;

其中记录了这么一个结构体(省略了源码中的大部分注释,有兴趣可以找到源码看一下),其中:

  ob_item是指向列表对象的指针数组;

  allocated是申请内存的槽的个数。

接着,通过源码获悉,python列表的存储形式就是以数组array的形式进行存储的,然后数组中每一个元素其实存储的是列表对象的指针。

现在我们搞明白了python列表的内部实现方式,所以进一步思考了如下问题:

1.对于列表操作,append操作肯定比insert操作效率要高:

  因为,对于数组来说,用append操作从后面追加一个元素,时间复杂度来说是常量级的,但是用insert操作进行数组的插入来说,当插入第一位或者中间某一位的时候,该元素后面的所有元素都要相应的往后面挪动一位。

2.python中列表的存储形式是数组的形式,这也突出了其和链表的很大的区别:

  a.当我们按照给定的索引值进行某一个元素的访问的话,数组的效率肯定是比链表的效率高出不少的。

     因为,对于数组来说,我们可以直接计算出目标元素在内存中的具体位置,然后直接对其访问;但是对于链表来说,我们要做的是去遍历整个链表才可以得到目标元素。

  b.但是对于插入insert操作来说,情况就和上面不同了。

     因为对于链表来说,我们只要知道在哪里执行insert插入操作就可以了,无论该列表中含有多少元素,操作时间都基本是相同的,造作的成本非常低;但是对于数组就不同了,每次执行插入操作的时候,都需要移动插入点右边的所有元素。甚至有时候,因为插入的元素过多,开始分配的内存空间不够,还需要把这个列表元素整体搬到一个更大的数组中(这是我开始的猜测)。当然,对于这种情况,python的开发者早就想好了对应的方法,就是append操作通常会采用一种动态数组或向量的特定解决方案:

       将内存分配得过大一些,并且等到其要溢出时,在线性时间内再次重新分配内存。

  但是,这样似乎还是我上面猜测的那样,不是会让append和insert一样糟糕么,其实不是这样子的,因为就算这俩种情况都有可能去搬动大量的元素,但最主要的不同是:对于append操作,发生的可能性要小非常多,事实上,我们能够确保每次搬入的数组都大于原数组一定的比例,那么该操作的平均成本(每次搬动的开销平均分摊到每次append操作中去),这样的时间复杂度通常是常量级别的。这里也从而得出来,python的列表对内存的开销是比较大的。

python中几个常见的“黑盒子”之 列表list的更多相关文章

  1. python中几个常见的黑盒子之“字典dict” 与 “集合set”

    这里说到"字典dict" 和 "集合set"类型,首先,先了解一下,对于python来说,标准散列机制是有hash函数提供的,对于调用一个__hash__方法: ...

  2. Python中执行系统命令常见的几种方法--转载

    Python中执行系统命令常见的几种方法 Python中执行系统命令常见的几种方法有: (1)os.system # 仅仅在一个子终端运行系统命令,而不能获取命令执行后的返回信息 # 如果再命令行下执 ...

  3. python中集合set,字典dict和列表list的区别以及用法

    python中set代表集合,list代表列表,dict代表字典 set和dict的区别在于,dict是存储key-value,每一个key都是唯一的,set相对于dict存储的是key,且key是唯 ...

  4. Python中3种内建数据结构:列表、元组和字典

    Python中3种内建数据结构:列表.元组和字典 Python中有3种内建的数据结构:列表.元组和字典.参考简明Python教程 1. 列表 list是处理一组有序项目的数据结构,即你可以在一个列表中 ...

  5. (四)Python中的“四大才子”(字符串、列表、字典、集合)

    前戏:在python中把数据序列分为可变(mutable)和不可变(immutable)两种 不可变:string.int.float.tuple 特点:相同对象只是占用一个内存地址,不管有多少个变量 ...

  6. python中字符串的常见操作方法

    1. 字符串概念,字符串是一个容器,包含若干个字符并按照一定的顺序组织成一个整体.字符串支持索引操作. 2. 创建字符串基本语法 变量名 = "字符串信息" 变量名 = '字符串信 ...

  7. python中字符串的常见操作

    demo:mystr = 'hello python' 1.find:mystr.find(str, start=0, end=len(mystr)),检测字符串中是否有要查询的字符,如果有返回开始的 ...

  8. Python中的数据类型常见方法

    list() 方法 1.cmp(list1, list2):#比较两个列表的元素 2.len(list):#列表元素个数 3.max(list):#返回列表元素最大值 4.min(list):#返回列 ...

  9. python中几个常见的魔法方法

    首先,什么是魔法方法呢?在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做"魔法"方法. __ init__()方法 当一个实例被创建的时候调用的初始 ...

随机推荐

  1. SQL超过锁请求

    ---超过锁请求 http://blog.sina.com.cn/s/blog_7fb3b1840100u4dj.html 1.查询造成死锁的SQL语句 当SQL数据库的监控报警显示死锁进程数过多时, ...

  2. EUI ToggleButton ToggleSwitch 实现类似音乐开关按钮

    一 ToggleButton和ToggleSwitch区别 没区别,就是继承... export class ToggleSwitch extends ToggleButton { /** * @la ...

  3. Res_Orders_01需求分析

    一.背景及好处 为了提高餐厅的运营效率,增强餐厅各部门间的配合,减少顾客到店后的点餐.等餐及结算过程消耗的时间,降低服务员点餐失误率,进一步提高餐厅管理人员对菜品.资金的管理以及更好的掌握餐厅的全局运 ...

  4. leetcode 6. ZigZag Conversion

    https://leetcode.com/problems/zigzag-conversion/ 题目: 将字符串转化成zigzag模式. 例如 "abcdefghijkmlnpq" ...

  5. SQL Server 数据类型映射

    SQL Server 和 .NET Framework 基于不同的类型系统. 例如,.NET Framework Decimal 结构的最大小数位数为 28,而 SQL Server 的 decima ...

  6. Java面试宝典答案详解与感悟(第一天)

    一.Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语法,集合的语法,io 的语法,虚拟机方面的语法. 1.一个".java&quo ...

  7. IDEA工具使用说明

    IDEA使用说明 1.安装 2.开始界面 1)create New Project (新建项目) 2)Import Project  (导入项目) 3)Open (打开已有的项目) 4)Check o ...

  8. Android_demo之生成二维码

    今天我们来学习一个自动生成二维码 的写法.我们经常能见到各种二维码,比如公众号的二维码,网址的,加好友的,支付的二维码等等.其实每一个二维码只是利用图片的形式展示出来的,实际是一些字符串.而这个字符串 ...

  9. html window.open 使用详解

    window.open ('page.html', 'newwindow', 'height=100, width=400, top=0, left=0, toolbar=no, menubar=no ...

  10. quartz_job

    quartz--job job是执行任务所需的Java类. 在quartz中job分为两种,有状态和无状态的.job是无状态的,statefuljob是有状态的. 通过实现job或者statefulj ...