本文出自“Python为什么”系列,请查看全部文章

在日常使用 Python 时,我们经常需要创建一个列表,相信大家都很熟练了吧?

# 方法一:使用成对的方括号语法
list_a = [] # 方法二:使用内置的 list()
list_b = list()

上面的两种写法,你经常使用哪一个呢?是否思考过它们的区别呢?

让我们开门见山,直接抛出本文的问题吧:两种创建列表的 [] 与 list() 写法,哪一个更快呢,为什么它会更快呢?

注:为了简化问题,我们以创建空列表为例进行分析。关于列表的更多介绍与用法说明,可以查看这篇文章

1、 [] 是 list() 的三倍快

对于第一个问题,使用timeit模块的 timeit() 函数就能简单地测算出来:

>>> import timeit
>>> timeit.timeit('[]', number=10**7)
>>> timeit.timeit('list()', number=10**7)

如上图所示,在各自调用一千万次的情况下,[] 创建方式只花费了 0.47 秒,而 list() 创建方式要花费 1.75 秒,所以,后者的耗时是前者的 3.7 倍!

这就回答了刚才的问题:创建空列表时,[] 要比 list() 快不少。

注:timeit() 函数的效率跟运行环境相关,每次执行结果会有微小差异。我在 Python3.8 版本实验了几次,总体上 [] 速度是 list() 的 3 倍多一点。

2、list() 比 [] 执行步骤多

那么,我们继续来分析一下第二个问题:为什么 [] 会更快呢?

这一次我们可以使用dis模块的 dis() 函数,看看两者执行的字节码有何差别:

>>> from dis import dis
>>> dis("[]")
>>> dis("list()")

如上图所示,[] 的字节码有两条指令(BUILD_LIST 与 RETURN_VALUE),而 list() 的字节码有三条指令(LOAD_NAME、CALL_FUNCTION 与 RETURN_VALUE)。

这些指令意味着什么呢?该如何理解它们呢?

首先,对于 [],它是 Python 中的一组字面量(literal),像数字之类的字面量一样,表示确切的固定值。

也就是说,Python 在解析到它时,就知道它要表示一个列表,因此会直接调用解释器中构建列表的方法(对应 BUILD_LIST ),来创建列表,所以是一步到位。

而对于 list(),“list”只是一个普通的名称,并不是字面量,也就是说解释器一开始并不认识它。

因此,解释器的第一步是要找到这个名称(对应 LOAD_NAME)。它会按照一定的顺序,在各个作用域中逐一查找(局部作用域--全局作用域--内置作用域),直到找到为止,找不到则会抛出NameError

解释器看到“list”之后是一对圆括号,因此第二步是把这个名称当作可调用对象来调用,即把它当成一个函数进行调用(对应 CALL_FUNCTION)。

因此,list() 在创建列表时,需要经过名称查找与函数调用两个步骤,才能真正开始创建列表(注:CALL_FUNCTION 在底层还会有一些函数调用过程,才能走到跟 BUILD_LIST 相通的逻辑,此处我们忽略不计)。

至此,我们就可以回答前面的问题了:因为 list() 涉及的执行步骤更多,因此它比 [] 要慢一些。

3、list() 的速度提升

看完前两个问题的解答过程,你也许觉得还不够过瘾,而且可能觉得就算知道了这个冷知识,也不会有多大的帮助,似乎那微弱的提升显得微不足道。

但是,我们Python猫出品的《Python为什么》系列一直秉承着孜孜不倦的求知精神,是不可能放着这个问题不去回答的。

而且,由于有发散性思考的习惯,我还想到了另外一个挺有意思的问题:list() 的速度能否提升呢?

我不久前写过一篇文章 正好讨论到这个问题,也就是在刚刚发布的 Python 3.9.0 版本中,它给 list() 实现了更快的 vectorcall 协议,因此执行速度会有一定的提升。

感兴趣的同学可以去Python 官网下载 3.9 版本。

根据我多轮的测试结果,在新版本中运行 list() 一千万次,耗时大概在 1 秒左右,也就是 [] 运行耗时的 2 倍,相比于前面接近 4 倍的数据,当前版本总体上是提升了不少。

至此,我们已回答完一连串的疑问,如果你觉得有收获,请点赞支持!欢迎大家关注后续更多精彩内容。

本文属于“Python为什么”系列(Python猫出品),该系列主要关注 Python 的语法、设计和发展等话题,以一个个“为什么”式的问题为切入点,试着展现 Python 的迷人魅力。所有文章将会归档在 Github 上,欢迎大家给颗小星星,项目地址:https://github.com/chinesehuazhou/python-whydo

Python 疑难问题:[] 与 list() 哪个快?为什么快?快多少呢?的更多相关文章

  1. 在python中创建列表的最佳和/或最快方法

    在python中,据我所知,至少有3到4种方法来创建和初始化给定大小的列表: 简单循环append: my_list = [] for i in range(50): my_list.append(0 ...

  2. 【转】TCP拥塞控制,慢启动、拥塞避免、快重传以及快恢复

    转自:http://blog.csdn.net/yusiguyuan/article/details/22847787 注:本文绝大部分是来自转载的博客,还补充了少量内容. 一.TCP的拥塞控制 拥塞 ...

  3. TCP超时重传、滑动窗口、拥塞控制、快重传和快恢复

    TCP超时重传 原理是在发送某一个数据以后就开启一个计时器,在一定时间内如果没有得到发送的数据报的ACK报文,那么就重新发送数据,直到发送成功为止. 影响超时重传机制协议效率的一个关键参数是重传超时时 ...

  4. TCP/IP学习笔记18--TCP--拥塞控制 (慢开始, 拥塞避免, 快重传和快恢复)

                                                            用最多的梦面对未来   -- 李嘉诚 在某段时间,若对网络资源的需求超过了该资源所能提供 ...

  5. 通信接口是webservice快还是scoket快解决方案

    通信接口是webservice快还是scoket快webservice和scoket都可以做为通信接口,一个走HTTP访问,一个走TCP协议访问 问1:通讯速度是webservice快还是scoket ...

  6. 计算机网络传输层之TCP拥塞控制(慢开始与拥塞避免、快重传和快恢复)

    文章转自:https://blog.csdn.net/weixin_43914604/article/details/105532044 学习课程:<2019王道考研计算机网络> 学习目的 ...

  7. 用python批量处理Excel表格,处理结果又快又好,做办公室最靓的那个仔

    使用python批量处理Excel数据     让你根据Excel上所有人的身份证号码,提取出公司员工的生日 让你每个月都将公司所有人的考勤数据整理一下 类似这样的格式化的重复操作,你还在每次都使用的 ...

  8. postman python疑难

    例子1:postman请求时会将默认的headers的content-type替换成Content-Type,而直接使用python的request则不行,服务器端就会接收到错误的Content-Ty ...

  9. 先贴上代码:Random快排,快排的非递归实现

    设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为主元,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序.值得注意的是, ...

随机推荐

  1. Spring security OAuth2.0认证授权学习第二天(基础概念-授权的数据模型)

    如何进行授权即如何对用户访问资源进行控制,首先需要学习授权相关的数据模型. 授权可简单理解为Who对What(which)进行How操作,包括如下: Who,即主体(Subject),主体一般是指用户 ...

  2. Myeclipse 连接数据库(jdbc)

    1.找到DataBase Explorer,如下图所示: 2.点击下图红框内图标,new 3.进入下图界面 如果是JDBC驱动按下图配置: driver name自己起 url一定要注意:jdbc:m ...

  3. Java实现文件夹下文件实时监控

    一.commons-io方法 1.使用Commons-io的monitor下的相关类可以处理对文件进行监控,它采用的是观察者模式来实现的 (1)可以监控文件夹的创建.删除和修改 (2)可以监控文件的创 ...

  4. Sunday算法解决字符串匹配问题

    概述 提起字符串匹配可能更多人会想到KMP算法,该算法时间复杂度为O(m+n),而且也是我们在学习数据结构过程中最早接触到的比较好的算法.但KMP算法需要在模式字符串有关联的情况下,也即模式字符串前后 ...

  5. ui自动化--xpath

    xpath //*代表从根节点,查找所有匹配到的元素.在filepath中输入后回车,会发现整个页面所有元素都被虚线选中 //表示跟节点 []代表要用属性定位 @表示要用什么属性 定位完成后,对应页面 ...

  6. 【NOIP2015模拟】终章-剑之魂

    背景介绍 古堡,暗鸦,斜阳,和深渊-- 等了三年,我独自一人,终于来到了这里-- "终焉的试炼吗?就在这里吗?"我自言自语道. "终焉的试炼啊!就在这里啊!"我 ...

  7. python 小脚本/自动重复访问网站(快速提高网页访问量)

    来到csdn也快两个月了,前前后后写了20篇博客,但才1800+的访问量,其中恐怕还有300多是我自己点的 有点桑心(┬_┬) 于是打算另辟蹊径,自己刷访问量代码如下,需要自取 import urll ...

  8. 吴恩达《深度学习》-课后测验-第一门课 (Neural Networks and Deep Learning)-Week 4 - Key concepts on Deep Neural Networks(第四周 测验 – 深层神经网络)

    Week 4 Quiz - Key concepts on Deep Neural Networks(第四周 测验 – 深层神经网络) \1. What is the "cache" ...

  9. [LeetCode] 448. 找到所有数组中消失的数字(思维)

    题目 给定一个范围在  1 ≤ a[i] ≤ n ( n = 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次. 找到所有在 [1, n] 范围之间没有出现在数组中的数字. 您 ...

  10. vSphere Client上安装虚拟机工具VMware Tools

    vSphere Client上安装虚拟机工具VMware Tools 1.安装虚拟机 具体安装步骤就不详述了,安装虚拟机之后右击虚拟机名->客户机->安装/升级VMware Tools,这 ...