当前位置: 首页 > news >正文

Python 中字符串、列表与对象解析实战:从字符串到 List,再到 Document 内容提取

在实际开发中,我们经常会遇到这样的数据:

  • 看起来像list,实际上是str
  • 看起来像对象,实际上只是对象的字符串描述
  • 从日志、数据库、接口返回的数据中恢复 Python 对象

今天通过两个真实案例,讲解如何正确处理。


一、问题一:字符串形式的 List 如何转换成真正 List?

1.1 场景

例如:

raw_str = '["qwen-turbo","qwen-plus","deepseek"]'

很多初学者会认为:

print(type(raw_str))

应该是:

<class 'list'>

但是实际:

print(type(raw_str))

结果:

<class 'str'>

原因:

它只是一个字符串。

里面的:

["qwen-turbo","qwen-plus","deepseek"]

只是字符。


1.2 错误方式:eval()

很多人第一反应:

result = eval(raw_str)

结果:

['qwen-turbo', 'qwen-plus', 'deepseek']

看起来可以。

但是:

不推荐!

原因:

eval()会执行 Python 代码。

例如:

data = "__import__('os').system('rm -rf /')" eval(data)

如果数据来自:

  • 用户输入
  • 网络请求
  • 数据库

可能造成安全问题。


1.3 推荐方式:ast.literal_eval()

Python 提供安全解析:

import ast raw_str = '["qwen-turbo","qwen-plus","deepseek"]' models = ast.literal_eval(raw_str) print(models) print(type(models))

输出:

['qwen-turbo', 'qwen-plus', 'deepseek'] <class 'list'>

1.4 literal_eval 支持哪些类型?

例如:

list

'["a","b"]'

转换:

["a","b"]

dict

"{'name':'deepseek'}"

转换:

{ "name":"deepseek" }

tuple

"(1,2,3)"

转换:

(1,2,3)

二、问题二:字符串中的 Document 对象如何获取 page?

这是 RAG 项目中非常常见的问题。

例如:

"[Document(metadata={'pk':12,'page':2}, page_content='xxx')]"

很多人看到:

Document

以为:

documents[0].page_content

可以访问。

但是实际上:

type(data)

结果:

<class 'str'>

它不是 Document。

只是:

一个包含 Document 文本描述的字符串。


三、为什么不能直接取 page?

错误:

data = "[Document(metadata={'page':2},page_content='hello')]" print(data[0].page)

错误:

AttributeError

因为:

data:

实际结构:

String | | 字符 | | [ D o c u m e n t ( ... )

Python 不知道:

Document

是什么对象。


四、正确解决方案一:不要让对象变字符串(最佳方案)

如果数据来源是 LangChain:

例如:

from langchain_core.documents import Document docs = [ Document( metadata={ "pk":12, "page":2 }, page_content="测试内容" ) ]

此时:

print(type(docs))

输出:

list

里面元素:

print(type(docs[0]))

输出:

Document

那么直接:

for doc in docs: print(doc.metadata["page"]) print(doc.page_content)

输出:

2 测试内容

五、真实场景:数据库里面保存成字符串怎么办?

很多项目:

比如:

mysql 字段: documents 内容: "[Document(...)]"

读取以后:

content = row.documents

变成:

str

怎么办?


方法1:正则提取 page_content

如果只是想获取文本:

import re text = """ Document(metadata={'page':2}, page_content='hello world') """ contents = re.findall( r"page_content='(.*?)'", text, re.S ) print(contents)

结果:

[ 'hello world' ]

然后:

result = "\n".join(contents)

得到:

hello world

六、方法2:重新构造 Document 对象

推荐在 RAG 项目中使用。

假设:

字符串:

doc_str

里面:

metadata page_content

解析:

from langchain_core.documents import Document docs=[] for item in解析后的数据: docs.append( Document( metadata=item["metadata"], page_content=item["page_content"] ) )

之后:

for doc in docs: print(doc.metadata["page"]) print(doc.page_content)

七、如果字符串格式固定,可以使用 ast + 转换

例如:

text = """ [ { "metadata":{ "page":2 }, "page_content":"hello" } ] """

转换:

import ast data = ast.literal_eval(text) for item in data: print(item["metadata"]["page"]) print(item["page_content"])

输出:

2 hello

八、RAG项目中的实际应用

在知识库系统里面:

流程:

PDF | ↓ Document对象 Document( metadata={ page:1 }, page_content="政策内容" ) | ↓ Embedding | ↓ Vector DB

检索回来:

应该保持:

List[Document]

例如:

docs = vector_store.similarity_search(question)

返回:

[ Document(...), Document(...) ]

然后:

for doc in docs: page = doc.metadata["page"] content = doc.page_content

生成引用:

来源: 政策文件.pdf 第2页 内容: xxxx

九、两个问题总结

问题本质解决方案
字符串 List 转 Liststr → listast.literal_eval()
字符串 Document 转对象str → Document不要序列化,或者重新构造
获取 page读取 metadatadoc.metadata["page"]
获取文本读取 page_contentdoc.page_content

十、最终记忆

开发中遇到:

看起来像对象

先问:

print(type(data))

如果:

str

不要直接:

data.xxx

先恢复对象。

RAG 开发尤其注意:

Document对象 ↓ 不要变成字符串 ↓ 保持 List[Document] ↓ metadata 保存来源 ↓ page_content 保存正文

这也是为什么 LangChain、LlamaIndex 等框架一直强调:

检索阶段保持 Document 对象结构,不要提前转成字符串。

http://www.jsqmd.com/news/1370122/

相关文章:

  • 平板坡口机V型、U型坡口切换方法,你知道吗?
  • 从纸质租赁合同到电子签,商铺房东租户当天就签妥
  • 从ReAct到Graph编排:构建复杂AI工作流的新范式
  • 数据洞察到业务落地的四步转化框架
  • NLP 模型评测与多任务性能对比:一次故障复盘能留下什么
  • 从DeepSeek到Kimi:AI模型本地部署与API集成实战指南
  • Win+G录屏音频故障全解析:从无声到高清音频提取
  • AI Agent 与滴答清单结合:从任务执行者到项目管理者
  • 2026年8月宁波6082铝件/红冲铝件源头厂家推荐_宁波市鄞州通润光电元件厂 - 行业平台推荐
  • 学生党怎么租游戏账号划算?按需选渠道很关键
  • AI提示词优化3D游戏开发工具链实战指南
  • 前端窗口导航全解析:从location.href到window.open的实战指南
  • 九大网盘直链解析工具:告别限速下载的完整解决方案
  • 解决方案工程师的成长之路(三)
  • Kimi K2.7深度压力测试:代码生成、架构设计与长文档处理实战评估
  • 5分钟掌握NCM文件解密:网易云音乐格式转换终极指南
  • Win10 拨号上网如何网络共享
  • 2026 年 8 月新发布:宣城可靠的金属雕花保温装饰一体板厂家哪家专业,老房翻新竟能省一半工期?这玩意儿让墙面保温又好看还不用反复折腾? - 行业严选官
  • Unity WebGL项目部署实战:服务器配置与优化全解析
  • Ray RLlib 架构入门指导
  • 【8月压轴会议投稿】18场EI高录用会议截稿倒计 | 2026年28-30日EIScopus国际学术会议合集:计算机//云计算/制造/人工智能等跨学科投稿优选清单,适用毕业结题/职称,高录用检索快!
  • Electron桌面应用开发入门与实践指南
  • AI Agent接入微信实战:基于Codex框架与iLink Bot API的集成方案
  • 深度解析Agentic RL中Rollout模块:从LLM推理到强化学习数据采集
  • OpenClaw-RL源码解析:离线策略蒸馏框架与智能体化强化学习实践
  • Trie树初步认识
  • 强化学习精通教程
  • 专业声卡硬件改装指南:实现Sonicake与Focusrite、RME等设备整合
  • 2027论文代写VS正规辅导怎么分?8家合规平台实测,新手零踩坑
  • 核心期刊论文AI写作工具打分:26年5款横评