Python中实现数组及预定义固定大小二维列表的更优方案
原生Python的优化方案
1. 固定大小二维列表的简洁构建
你目前用列表推导式预定义的思路是对的,但是可以大幅简化写法:
- 非锯齿数组:直接用
[['null'] * 列数 for _ in range(行数)]即可,不需要嵌套两层for循环的推导式,和你的实现效果完全一致。
注意避坑:不要写[['null']*列数] * 行数,这种写法会导致所有行都是同一个列表的引用,修改某一行会同步修改所有行,这是新手常见错误
示例代码:
# 生成3行4列的预填充列表 output = [['null'] * 4 for _ in range(3)]
- 锯齿数组:直接用一层列表推导即可实现,不需要多层循环:
# 按照输入的锯齿数组结构生成等大小的预填充列表 jagged_arr = [[1,2], [3], [4,5,6]] output = [['null'] * len(row) for row in jagged_arr] # 列数列表直接生成 col_counts = [len(row) for row in jagged_arr]
2. 不需要预定义占位符的场景优化
很多时候你不需要提前创建占位符列表,比如你写的矩阵转置功能,Python原生支持更简洁的实现,完全不需要提前创建空列表、嵌套循环赋值:
def transpose(m): return list(map(list, zip(*m)))
zip(*m)会直接把输入的二维列表按列打包,再转成列表就是转置后的结果,和你现有实现的效果完全一致。
3. 你写的arraybuilder函数优化
首先要修复一个经典bug:Python的函数默认参数不要用可变对象(比如你写的jagged=[]),这个参数只会在函数定义时初始化一次,多次调用函数时会复用同一个列表,导致意料之外的结果,建议修改为jagged=None,函数内部再初始化空列表。
优化后的完整代码:
def arraybuilder(r, c, jagged=None): if jagged is None: jagged = [] if not jagged: return [["null" for _ in range(c)] for _ in range(r)] else: output = [["null"] * len(row) for row in jagged] noOfColumns = [len(row) for row in jagged] return output, noOfColumns
更接近Java数组的替代方案
如果你想要和Java数组更接近的、同类型、固定大小的数组结构,不需要引入第三方库,可以用Python标准库自带的array模块,它支持存储同类型的基础数据(比如整数、浮点数),内存占用比列表更低,行为更接近Java的原生数组:
import array # 生成一个长度为5、元素类型为整数的数组,对应Java的int[] arr = array.array('i', [0]*5)
如果后续你能接受第三方库,numpy的ndarray是数值计算场景下的最优选择,完全匹配Java数组的索引、矩阵操作习惯,性能也远高于原生列表。
内容的提问来源于stack exchange,提问作者Arin Paliwal
相关产品推荐
相关产品推荐

