能否预分配Python列表内存后使用append方法填充?
编写代码时,我大致知晓列表的长度,但精确计算初始合适长度需处理诸多问题,比如避免末尾多余None干扰、防止后续索引越界。目前我只能选择两种方式:
一是预分配内存后通过索引赋值,示例代码:
A = [None]*1000 for i in range(1000): A[i] = 1
二是创建空列表后用list.append()填充,示例代码:
B = [] for i in range(1000): B.append(1)
我想知道是否存在折中方案:能否为列表预分配约1000单位内存,使用append时在实际元素末尾添加,而非在设置的None之后?如下(无法正常运行)的设想是否可行:
A = [None]*1000 for i in range(1000): A.append(1)
Python列表是否支持该操作?还是需使用其他数据结构?
回答
你设想的代码不可行,A = [None]*1000会创建一个包含1000个None元素的列表,调用append()会在这些None之后追加元素,最终列表会有2000个元素(1000个None+1000个1),完全不符合需求。
核心说明
Python列表本身就是动态数组,底层会自动预分配内存空间:当你调用append()时,如果当前预分配的内存还没满,就直接在末尾添加元素,无需重新扩容;只有当元素数量超过预分配容量时,才会触发扩容(通常按1.5倍或2倍的比例扩容)。所以直接用空列表B = []然后append()的方式,其实已经在享受Python自动内存预分配的优化,没必要手动用[None]*n来预分配。
折中方案(手动预分配内存且无多余None)
如果确实想手动控制预分配的内存容量(比如明确要添加1000个元素,想彻底避免扩容开销),可以先创建指定长度的列表再清空:
A = [None] * 1000 A.clear() # 清空列表,此时长度为0,但底层保留了能容纳1000个元素的内存 for i in range(1000): A.append(1)
这样append()时会直接在空列表末尾添加元素,既利用了预分配的内存,又不会有多余的None干扰。
替代数据结构
如果不需要列表的随机访问特性,也可以使用collections.deque,它的append()操作效率极高,内存管理更灵活,但deque的随机访问速度不如普通列表。
内容的提问来源于stack exchange,提问作者Lily

