在Python中创建列表——有什么诡异的事情吗?
抱歉,如果这段话让你感到困惑,我对Python还很陌生!
通过在解释器中测试,我发现list()
和[]
都可以生成一个空列表:
>>> list()
[]
>>> []
[]
根据我目前的学习,创建一个对象的唯一方法是调用它的构造函数(__init__
),但是当我只输入[]
时,并没有看到这个过程。那么,当我执行[]
时,Python是不是把它当作调用list()
来处理呢?
7 个回答
使用 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 和 [] 之间的区别 的帖子。
这两种写法的处理方式完全不同:
>>> 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
这个对象的构造函数。
不,Python并不会调用list()
,否则你就可以通过给list赋值来改变[]
创建的类型,但这是不可能的:
>>> import __builtin__
>>> __builtin__.list = set
>>> list()
set([])
>>> []
[]
[]
是用来创建列表的语法。这是一个内置类型,它有自己特殊的语法,就像字典、字符串、整数、浮点数以及很多其他类型一样。
创建类型的实例也可以通过调用类型来完成,比如list()
——这会自动调用该类型的构造函数和初始化函数。直接调用初始化函数(__init__
)并不会创建一个新的类型实例。调用构造函数(__new__
)会创建一个,但你不应该直接调用它。