jinchanchan 发表于 2025-3-14 14:45:05

在 Python 中创建列表时,应该写 `[]` 还是 `list()`?

本帖最后由 jinchanchan 于 2025-3-14 14:46 编辑

在 Python 中,创建列表有两种写法:
# 写法一:使用一对方括号
list_1 = []
# 写法二:调用 list()
list_2 = list()
那么哪种写法更好呢?
单从写法上来看,[] 要比 list() 简洁,那在性能和功能方面,二者又有怎样的差异呢?
使用 [] 创建列表的速度比使用 list() 快
我们先使用 timeit 来测量一下这两种写法创建 100 万次空列表所花费的时间。timeit 是 Python 标准库中的一个模块,常用于测量小段代码的执行时间,非常适合性能测试和比较不同实现的效率。
import timeit
time_list = timeit.timeit('list()', number=1000000)
time_brackets = timeit.timeit('[]', number=1000000)
print(f"list()的耗时: {time_list} 秒")
print(f"[]的耗时: {time_brackets} 秒")
# list()的耗时: 0.04899674400803633 秒
# []的耗时: 0.02433863200712949 秒
我们发现使用 [] 创建列表的速度比使用 list() 快。那为什么前者的速度更快呢?
我们可以借助 dis 模块,从这两种写法对应的字节码上看一看差别。dis.dis() 函数可以反汇编一段 Python 代码,显示它的字节码指令,以帮助开发者了解 Python 代码在底层是如何执行的。
import dis # pip3 install dis
print("Disassembly of create_list_with_list:")
dis.dis('list()')
print("Disassembly of create_list_with_brackets:")
dis.dis('[]')
这段脚本的运行结果如下:
Disassembly of create_list_with_list:
0         0 RESUME                   0

1         2 PUSH_NULL
            4 LOAD_NAME                0 (list)
            6 CALL                     0
             14 RETURN_VALUE
Disassembly of create_list_with_brackets:
0         0 RESUME                   0

1         2 BUILD_LIST               0
            4 RETURN_VALUE
由此不难发现,[] 和 list() 执行速度上的差异主要是因为执行的字节码指令不同。
[] 是一个直接生成列表的字面量(literal),只使用 BUILD_LIST 指令即可生成一个空列表。而 list() 是一个生成列表的函数,它需要先使用 LOAD_NAME 指令加载函数,然后通过 CALL 指令调用该函数。这个额外的步骤带来的开销就导致这种写法要比 [] 慢。
除了 dis 模块,也可通过 godbolt.org/z/T39KesbPf这个网站来对比这两种写法的差别:
二者在功能上的差异
[] 和 list() 都能创建空的列表,但在创建含有元素的列表时,二者的用法有所不同。
list() 可以接受一个(且只能是一个)可迭代对象作为参数,并将其转换为列表:
# 从可迭代对象创建列表
list_from_tuple = list((1, 2, 3)) #
list_from_string = list("hello")# ['h', 'e', 'l', 'l', 'o']
list_from_dict_keys = list({"a": 1, "b": 2}.keys()) # ['a', 'b']
而在使用 [] 创建非空列表时,需要一一列举出其中的元素:
list_nums =
list_letters = ["a", "b", "c", "d"]
[] 不能直接将可迭代对象转换为列表。
综上所述,当需要创建一个空列表时,[] 是更简洁和高效的选择。而当需要将可迭代对象转换为列表时,就需要使用 list() 了。

FishC 发表于 2025-3-14 14:45:19

在 Python 中创建列表时,应该使用 `[]` 还是 `list()`?

在 Python 中,创建列表有两种常见的写法:

[*]使用方括号 `[]`:
list_1 = []

[*]使用 `list()` 函数:
list_2 = list()


那么哪种写法更好呢?

性能对比:`[]` 更快

我们可以使用 `timeit` 模块来测试两种方法创建 100 万次空列表的耗时:

import timeit

time_list = timeit.timeit('list()', number=1000000)
time_brackets = timeit.timeit('[]', number=1000000)

print(f"list()的耗时: {time_list} 秒")
print(f"[] 的耗时: {time_brackets} 秒")

示例输出:
list()的耗时: 0.0489 秒
[] 的耗时: 0.0243 秒

可以看到,使用 `[]` 创建列表的速度比 `list()` 更快。

为什么 `[]` 更快?

我们可以使用 `dis` 模块查看两种写法的字节码指令:

import dis

print("Disassembly of list():")
dis.dis('list()')

print("Disassembly of []:")
dis.dis('[]')

输出结果:

Disassembly of list():
0         0 RESUME                   0
1         2 PUSH_NULL
            4 LOAD_NAME                0 (list)
            6 CALL                     0
             14 RETURN_VALUE

Disassembly of []:
0         0 RESUME                   0
1         2 BUILD_LIST               0
            4 RETURN_VALUE

从字节码可以看出:

[*]`[]` 直接使用 `BUILD_LIST` 指令创建列表,执行步骤更少。
[*]`list()` 需要先 `LOAD_NAME` 加载 `list` 函数,再 `CALL` 进行调用,额外的步骤导致性能稍慢。

功能对比:`list()` 更灵活

虽然 `[]` 更快,但 `list()` 具有更强的功能,它可以将可迭代对象转换为列表:

list_from_tuple = list((1, 2, 3))# 从元组创建列表
list_from_string = list("hello")# 从字符串创建列表
list_from_dict_keys = list({"a": 1, "b": 2}.keys())# 从字典键创建列表

而 `[]` 只能用于直接创建列表,不能将可迭代对象转换为列表:

list_nums =
list_letters = ['a', 'b', 'c']

结论

[*]如果只是创建一个空列表,`[]` 更简洁且性能更优。
[*]如果需要将可迭代对象转换为列表,必须使用 `list()`。

因此,在大多数情况下,推荐使用 `[]` 来创建空列表,而在需要转换可迭代对象时使用 `list()

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

player-none 发表于 2025-3-14 19:19:32

我由此发现了Python的一个缺陷,{}表示字典(按照你的推论会比dict()快),但集合也是{},单独使用只能用set()……

小甲鱼的二师兄 发表于 2025-3-14 19:21:00

[] 直接使用字面量语法创建列表,通常比 list() 更快,因为 list() 需要额外的函数调用开销。

小甲鱼的二师兄 发表于 2025-3-14 19:24:56

player-none 发表于 2025-3-14 19:19
我由此发现了Python的一个缺陷,{}表示字典(按照你的推论会比dict()快),但集合也是{},单独使用只能用set ...

字典(dict) 是 键-值(key-value)对 的数据结构。
集合(set) 只存储键(key),但没有对应的值,可以被视为一种特殊的字典,其中所有键的值都为 None。

player-none 发表于 2025-3-14 19:32:30

小甲鱼的二师兄 发表于 2025-3-14 19:24
字典(dict) 是 键-值(key-value)对 的数据结构。
集合(set) 只存储键(key),但没有对应的值,可 ...

1.和我说的创建空set毫无关系
2.数据来说话

from timeit import timeit as test
test('{1,2,3,4,5,6}',number=1000000)
# 0.18425100000013117
test('{1:None,2:None,3:None,4:None,5:None,6:None}',number=1000000)
# 0.26571599999988393

from dis import dis
dis('{1,2,3,4,5,6}')
# :
0         0 RESUME                   0

1         2 BUILD_SET                0
            4 LOAD_CONST               0 (frozenset({1, 2, 3, 4, 5, 6}))
            6 SET_UPDATE               1
            8 RETURN_VALUE

dis('{1:None,2:None,3:None,4:None,5:None,6:None}')

# :
0         0 RESUME                   0

1         2 LOAD_CONST               0 (None)
            4 LOAD_CONST               0 (None)
            6 LOAD_CONST               0 (None)
            8 LOAD_CONST               0 (None)
             10 LOAD_CONST               0 (None)
             12 LOAD_CONST               0 (None)
             14 LOAD_CONST               1 ((1, 2, 3, 4, 5, 6))
             16 BUILD_CONST_KEY_MAP      6
             18 RETURN_VALUE

鱼cpython学习者 发表于 2025-3-15 14:01:21

player-none 发表于 2025-3-14 19:32
1.和我说的创建空set毫无关系
2.数据来说话

他的说法只是便于理解,不代表两者等价,更不代表这两者在解释器看来是没有区别的,因此性能也不会一致。而对于缺陷的说法,仁者见仁吧。dictionary是更早引入的数据结构,而且键值存储相对而言也更加常用,说是一种取舍也不为过
页: [1]
查看完整版本: 在 Python 中创建列表时,应该写 `[]` 还是 `list()`?