HOWTO · Python

在 Python 中初始化一个空列表

说明如何创建真正的空列表,以及如何用 n 个实际的 None 元素初始化列表;Python 列表仍可调整长度。

本页内容

在 Python 中,[] 和 list() 都会创建长度为零的列表。如果需要预先创建已知数量的索引位置,[None] * n 会创建包含 n 个实际元素的列表;它不会预留容量,也不会让列表变成固定长度。应根据需求选择:是随着值陆续到来而收集,还是一开始就需要可按索引访问的位置。

使用 [] 创建空列表

方括号是创建新列表时简洁而常见的写法。它可以自然地用于赋值、函数参数和表达式中。下面的小程序还展示了常见做法:先创建一个新列表,再随着操作进展逐个添加值。程序可以独立运行,并会在添加两项后打印列表;每次追加元素时,列表都会增长。如果每次运行都需要独立的列表对象,请使用新的赋值操作。

运行此示例:

本节中的代码以及显示的标签或输出仍为英文。

items = []
items.append("tea")
items.append("bread")
print(items)
['tea', 'bread']

将空列表赋给 items 时,会创建一个不含元素的列表。每次调用 append() 都会在末尾添加一个元素。如果要添加另一个可迭代对象中的每个元素,请使用 extend(iterable);如果要在特定位置插入项目,请使用 insert(index, value)。Python 列表是可变的,因此创建后仍可增长或缩短。

使用 list() 创建空列表

不带参数调用内置的 list() 构造函数,也会创建一个长度为零的新列表。当构造函数能让代码意图更清楚,或同一表达式还会在代码的另一个分支中接收可迭代对象时,这种写法会很方便。传入可迭代对象时,list(source) 会创建一个包含其元素的新列表;不传参数时,结果是 []。

本节中的代码以及显示的标签或输出仍为英文。

items = list()
print(len(items), items)
0 []

对于直接创建列表字面量的情况,[] 更短,也很常用。这两种写法都会得到空列表,因此选择在当前代码中读起来更清楚的一种即可。每次执行时,两者都会创建一个新列表;它们都不会自动创建共享列表。

初始化具有固定数量位置的列表

如果在各个位置的值尚未就绪时,已经知道所需的索引位置数量,可以将只包含一个 None 的列表乘以该数量。这里的 None 是 Python 的单例值,可用来标记尚未填入实际值的位置。这个表达式会创建长度为 count 的列表,每个位置都包含一个 None。它不会预先分配隐藏容量,生成的列表仍可扩展或缩短。

本节中的代码以及显示的标签或输出仍为英文。

count = 3
slots = [None] * count
slots[1] = "ready"
print(slots)
[None, 'ready', None]

按索引赋值会替换该位置上的元素;有效索引从零开始。对于 None 或数字等简单的不可变标记,可以使用这种写法。如果默认值是可变对象,例如内部列表,列表乘法会重复引用同一个对象,因此修改一个位置时,看起来可能所有位置都随之改变。可以改用推导式来创建彼此独立的可变值,例如 [[] for _ in range(count)]。

初始化后向列表添加值

如果值会陆续到来,或者最终数量尚不确定,请从 [] 开始。每当有值可用时就追加;要一次添加一批值,请使用 extend()。收集输入、筛选结果或在循环中构建输出时,通常会采用这种方式。也可以先用 list() 初始化列表,再以相同方式更新它。

本节中的代码以及显示的标签或输出仍为英文。

scores = []
for score in (8, 10, 9):
    scores.append(score)
print(scores)
[8, 10, 9]

如果已经通过 [None] * count 创建了各个位置,并且想填入已有位置,请按索引赋值,而不是追加。追加会在当前末尾之后新增一个元素,因此会增加列表长度,而不是替换标记。只有目标位置已经存在时,才能为该索引赋值。

如何选择空列表或预填位置

如果希望集合从不含元素开始,并随着值的到来逐步增长,请使用 [] 或 list()。如果需要立即创建 count 个实际位置,并稍后按索引替换其中的标记值,请使用 [None] * count。“固定数量的位置”描述的是列表的初始内容,并不表示长度上限:无论采用哪种方式,Python 列表都可以调整长度。

直接创建列表字面量时,[] 简洁明了;list() 可以强调构造过程,也可以用于转换可迭代对象;列表乘法则适合重复不可变值或 None 标记。如果每个位置都需要独立的内部列表,请避免使用 [[]] * count,因为每个位置都指向同一个内部列表。像 [[] for _ in range(count)] 这样的推导式会在每个位置创建单独的内部列表。选择能清楚表达你是在累积值,还是在填充已有位置的写法。