Python保存列表至Excel时转为字符串的问题及解决方案咨询
解决Pandas保存列表到Excel时转为字符串的问题
问题原因
Excel本身没有原生的列表数据类型,Pandas在将列表写入Excel时,会默认把列表转换为字符串格式存储;后续从Excel读取数据时,这些内容依然是字符串,无法直接作为列表对象使用。
解决方案
最通用且兼容性好的方法是用JSON序列化列表:保存时将列表转为JSON格式的字符串,读取时再解析JSON字符串还原成列表。这种方式既能保留列表的结构,又能完美适配Excel的存储格式。
如果业务允许,也可以选择将列表拆分到多行(同一主键对应列表每个元素的单独行),但该方法仅适合特定场景。
修改后的代码示例
import streamlit as st import pandas as pd import json df_path = 'database/meters_try.xlsx' # 读取Excel时解析JSON字符串为列表 def read_excel_with_lists(path): try: df = pd.read_excel(path) # 定义需要解析为列表的列(根据你的业务调整列名) list_columns = ["column1", "column3", "column6", "column7", "column8", "column9", "column10", "column11"] for col in list_columns: df[col] = df[col].apply(lambda x: json.loads(x) if isinstance(x, str) and x.startswith('[') else x) return df except FileNotFoundError: # 文件不存在时创建空DataFrame return pd.DataFrame(columns=["column1", "column2", "column3", "column4", "column5", "column6", "column7", "column8", "column9", "column10", "column11", "column12"]) df = read_excel_with_lists(df_path) a = ['2023-02-11'] b = 'PR' c = ['A', 'B'] d = 'AAA' e = 'SHIFT' f = ['PERSON1', 'PERSON2'] g = ['PERSON3', 'PERSON4', 'PERSON5'] h = ['QQ'] i = ['0'] j = ['50', '110'] k = ['50', '60'] l = 'NOTES.' # 查看变量类型 st.write(f"b的类型: {type(b)}") st.write(f"c的类型: {type(c)}") def add_data(a, b, c, d, e, f, g, h, i, j, k, l): # 将列表转为JSON字符串,非列表内容直接返回 def serialize_list(item): return json.dumps(item) if isinstance(item, list) else item temp_df = pd.DataFrame({ "column1": [serialize_list(a)], "column2": [b], "column3": [serialize_list(c)], "column4": [d], "column5": [e], "column6": [serialize_list(f)], "column7": [serialize_list(g)], "column8": [serialize_list(h)], "column9": [serialize_list(i)], "column10": [serialize_list(j)], "column11": [serialize_list(k)], "column12": [l] }) df_meters = read_excel_with_lists(df_path) # 用concat替代已废弃的append方法 df_meters = pd.concat([df_meters, temp_df], ignore_index=True) df_meters.to_excel(df_path, index=False) st.write(df_meters) button = st.button("Save!") if button: add_data(a, b, c, d, e, f, g, h, i, j, k, l) st.success("Saved") def find_column_data_type(df): for col in df.columns: # 处理空列情况,取第一个非空值判断类型 first_val = df[col].dropna().iloc[0] if not df[col].dropna().empty else None col_type = type(first_val) if first_val is not None else "空列" st.write(f"{col} 列的数据类型: {col_type}") if st.button("查看各列数据类型"): find_column_data_type(df)
代码说明
- 序列化与反序列化:用
json.dumps()把列表转成JSON字符串存入Excel,读取时用json.loads()解析回列表结构。 - 空文件兼容:添加文件不存在时创建空DataFrame的逻辑,避免运行报错。
- 方法更新:用
pd.concat()替代已废弃的append(),符合Pandas最新规范。 - 类型检查优化:处理空列场景,避免取第一个值时出现索引错误。
内容的提问来源于stack exchange,提问作者volkan
相关产品推荐
相关产品推荐

