在Python中创建列表——有什么诡异的事情吗?

11 投票
7 回答
4329 浏览
提问于 2025-04-15 22:09

抱歉,如果这段话让你感到困惑,我对Python还很陌生!

通过在解释器中测试,我发现list()[]都可以生成一个空列表:

>>> list()
[]
>>> []
[]

根据我目前的学习,创建一个对象的唯一方法是调用它的构造函数(__init__),但是当我只输入[]时,并没有看到这个过程。那么,当我执行[]时,Python是不是把它当作调用list()来处理呢?

7 个回答

6

使用 list() 和 [] 之间的主要区别是什么?

list() 和 [] 之间最明显的区别就是它们的写法。暂时不谈写法,如果你刚接触 Python,可能会觉得它们都是列表,或者说它们来自同一个类;这确实是对的。这也让理解它们之间的关键区别变得更加重要,下面会详细说明这些区别。

list() 是一个函数,而 [] 是一种 字面量语法

我们来看看当我们分别调用 list() 和 [] 时,发生了什么,通过反汇编工具可以看到。

>>> import dis
>>> print(dis.dis(lambda: list()))
  1           0 LOAD_GLOBAL              0 (list)
              3 CALL_FUNCTION            0 (0 positional, 0 keyword pair)
              6 RETURN_VALUE
None
>>> print(dis.dis(lambda: []))
  1           0 BUILD_LIST               0
              3 RETURN_VALUE
None

上面的反汇编输出显示,字面量语法版本不需要进行全局查找,这一点用操作码 LOAD_GLOBAL 表示,也不需要调用函数,用操作码 CALL_FUNCTION 表示。

因此,字面量语法比它的对应版本要快。我们花点时间看看下面的时间测试结果。

import timeit
>>> timeit.timeit('[]', number=10**4)
0.0014592369552701712
>>> timeit.timeit('list()', number=10**4)
0.0033833282068371773

另外,值得注意的是,字面量语法 [] 不会解包值。下面是一个解包的例子。

>>> list('abc') # unpacks value
['a', 'b', 'c']
>>> ['abc'] # value remains packed
['abc']

什么是 Python 中的字面量?

字面量是 Python 识别的常量或原始变量值的写法,属于内置类型。

内容来源于我在 PythonRight - list 和 [] 之间的区别 的帖子。

13

这两种写法的处理方式完全不同:

>>> import dis
>>> def f(): return []
... 
>>> dis.dis(f)
  1           0 BUILD_LIST               0
              3 RETURN_VALUE        
>>> def f(): return list()
... 
>>> dis.dis(f)
  1           0 LOAD_GLOBAL              0 (list)
              3 CALL_FUNCTION            0
              6 RETURN_VALUE        
>>> 

[]这种写法是用一个叫做BUILD_LIST的指令来创建一个列表,而list()这种写法则是调用了list这个对象的构造函数。

7

不,Python并不会调用list(),否则你就可以通过给list赋值来改变[]创建的类型,但这是不可能的:

>>> import __builtin__
>>> __builtin__.list = set
>>> list()
set([])
>>> []
[]

[]是用来创建列表的语法。这是一个内置类型,它有自己特殊的语法,就像字典、字符串、整数、浮点数以及很多其他类型一样。

创建类型的实例也可以通过调用类型来完成,比如list()——这会自动调用该类型的构造函数和初始化函数。直接调用初始化函数(__init__)并不会创建一个新的类型实例。调用构造函数(__new__)会创建一个,但你不应该直接调用它。

撰写回答