
CSV 文件本身不支持嵌套数据结构,csv.writer 会将每个内层列表转为字符串写入,读取时需用 ast.literal_eval 安全还原为 Python 列表,才能恢复原始嵌套结构。
csv 文件本身不支持嵌套数据结构,`csv.writer` 会将每个内层列表转为字符串写入,读取时需用 `ast.literal_eval` 安全还原为 python 列表,才能恢复原始嵌套结构。
在 Python 中,csv 模块专为处理二维表格数据(即“行 × 列”)而设计。当你尝试写入形如 [[[1,2,3], [4,5,6]], [[7,8,9], [10,11,12]]] 的三层嵌套列表时,csv.writer.writerows() 实际上是将每一行(如 [[1,2,3], [4,5,6]])作为可迭代对象展开——此时每个子列表 [1,2,3] 被自动转换为字符串 '[1, 2, 3]' 并以逗号分隔写入 CSV。因此,读取时 csv.reader 返回的只是字符串列表,而非原始嵌套结构。
解决该问题的关键在于:写入时保持语义清晰,读取时主动解析字符串为 Python 对象。推荐使用 ast.literal_eval() ——它安全、轻量,仅支持基本字面量(list, tuple, dict, int, float, str, bool, None),可防止代码注入风险,远比 eval() 可靠。
以下是一个完整、可直接运行的解决方案:
import csv
import ast
# 原始嵌套列表:三维结构(行 × 子行 × 元素)
data = [
[[1, 2, 3], [4, 5, 6], [7, 8, 9]],
[[1, 2, 3], [4, 5, 6], [7, 8, 9]],
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
]
# ✅ 写入 CSV:每行对应一个外层列表,各子列表转为字符串存储
with open("nested_data.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerows(data) # 自动调用 str() 处理每个子列表
# ✅ 读取并还原:对每一列字符串执行 literal_eval
with open("nested_data.csv", "r", newline="") as f:
reader = csv.reader(f)
restored = [[ast.literal_eval(cell) for cell in row] for row in reader]
print("原始数据:")
print(data)
print("\n还原后数据(类型与结构一致):")
print(restored)
print("\n验证一致性:", data == restored) # True
⚠️ 注意事项:
- 不要用 json 替代 csv? 若数据结构复杂或需跨语言兼容,建议改用 JSON(json.dump()/json.load()),它原生支持任意嵌套;但若必须用 CSV(如需 Excel 打开、配合其他工具链),则 ast.literal_eval 是最简方案。
- 避免 eval():eval() 可执行任意代码,存在严重安全隐患;ast.literal_eval() 仅解析字面量,是唯一推荐的安全替代。
-
空值与异常处理:生产环境中建议添加异常捕获,例如:
try: parsed = ast.literal_eval(cell) except (ValueError, SyntaxError): raise ValueError(f"Invalid literal in CSV cell: {cell!r}")
总结:CSV 是文本表格格式,不是序列化协议。面对嵌套结构,写入即“序列化为字符串”,读取需“反序列化回对象”。ast.literal_eval() 提供了安全、标准、零依赖的还原能力,是处理此类场景的最佳实践。











