
本文介绍使用 itertools.zip_longest 对 numpy 中的不规则二维数组(jagged array)进行安全转置的方法,并过滤掉填充的 none 值,最终得到符合预期的嵌套列表结构。
在标准线性代数或 NumPy 中,“转置”通常要求输入是规则的矩形数组(即每行长度相同),但现实场景中常遇到锯齿状数组(jagged array)——各行长度不一,例如座位排布、稀疏日志记录或变长序列数据。此时直接调用 np.transpose() 或 arr.T 会报错(ValueError: axis 1 is out of bounds for array of dimension 1),而普通 zip(*seats) 又会按最短行截断,丢失数据。
正确做法是使用 itertools.zip_longest:它能以最长行为基准对齐各列,自动用指定填充值(默认为 None)补齐缺失位置。配合列表推导式即可优雅实现“非截断式转置”。
以下是完整示例代码:
import numpy as np
from itertools import zip_longest
seats = np.array([
[1, 2, 3, 4, 5],
[1, 2, 3, 4],
[1, 2, 3],
[1, 2, 3, 4],
[1, 2],
[1, 2]
], dtype=object)
# 步骤 1:使用 zip_longest 按列对齐(补 None)
padded_transpose = list(zip_longest(*seats))
# 输出:[(1,1,1,1,1,1), (2,2,2,2,2,2), (3,3,3,3,None,None), ...]
# 步骤 2:过滤掉 None,得到纯净转置结果
transposed_seats = [list(filter(lambda x: x is not None, col)) for col in padded_transpose]
# 或更清晰的写法:
transposed_seats = [[x for x in col if x is not None] for col in padded_transpose]
print(transposed_seats)
# [[1, 1, 1, 1, 1, 1],
# [2, 2, 2, 2, 2, 2],
# [3, 3, 3, 3],
# [4, 4, 4],
# [5]]⚠️ 注意事项:
立即学习“Python免费学习笔记(深入)”;
- dtype=object 是必需的,否则 NumPy 会尝试强制统一类型并可能报错或静默截断;
- 若原始数据含 None 值且需保留,应改用其他唯一哨兵值(如 float('nan') 或自定义对象)并调整过滤逻辑;
- 此方法返回的是 Python 嵌套列表,如需转回 np.ndarray(dtype=object),可进一步调用 np.array(transposed_seats, dtype=object);
- 性能敏感场景下,避免在超大锯齿数组上使用——zip_longest 是纯 Python 实现,不如向量化操作高效,此时建议先规整化数据(如填充至统一长度)再转置。
总结:对于不规则二维结构,zip_longest + 列表推导是清晰、健壮且符合 Pythonic 风格的转置方案,兼顾可读性与实用性。










