列表推导式处理None值:用BeautifulSoup提取XML中Speaker信息
提取带可选头衔的演讲者姓名
问题背景
我有一个存储演讲者信息的XML文件,结构如下:
<speakerlist> <speaker> <title>Dr.</title> <firstname>Bernd</firstname> <lastname>Baumann</lastname> </speaker> <speaker id="11003218"> <firstname>Karsten</firstname> <lastname>Schneider</lastname> <info>(Erfurt)</info> </speaker> ... </speakerlist>
其中firstname、lastname为必填字段,title、info为可选字段。需要以简洁方式提取包含可选头衔的演讲者姓名。
仅提取基础姓名的代码可以正常运行:
[speaker.find("firstname").text + " " + speaker.find("lastname").text for speaker in speakerlist.find_all("speaker")]
但尝试添加可选头衔时,以下代码会报错:
[ speaker.find("title").text + " " + speaker.find("firstname").text + " " + speaker.find("lastname").text if speaker.find("title").text is not None else speaker.find("firstname").text + " " + speaker.find("lastname").text for speaker in speakerlist.find_all("speaker") ]
错误信息:
'NoneType' object has no attribute 'text'
原因是当title不存在时,speaker.find("title")返回None,直接调用.text会触发属性错误。
解决方案
写法1:利用海象运算符简化判断
[ f"{title.text} {fn.text} {ln.text}" if (title := speaker.find('title')) else f"{fn.text} {ln.text}" for speaker in speakerlist.find_all("speaker") for fn, ln in [(speaker.find('firstname'), speaker.find('lastname'))] ]
通过海象运算符:=先获取并判断title元素是否存在,同时提前缓存firstname和lastname的查询结果,避免重复查找。
写法2:列表过滤拼接(最简洁)
[ " ".join([part.text for part in [speaker.find('title'), speaker.find('firstname'), speaker.find('lastname')] if part]) for speaker in speakerlist.find_all("speaker") ]
将所有可能的字段放入列表,过滤掉None值后用空格拼接,自动忽略不存在的title,代码简洁且易读。
写法3:可选头衔单独处理
[ (f"{title.text} " if (title := speaker.find('title')) else "") + speaker.find('firstname').text + " " + speaker.find('lastname').text for speaker in speakerlist.find_all("speaker") ]
仅针对title做可选拼接,基础姓名直接组合,兼顾简洁性和可读性。
内容的提问来源于stack exchange,提问作者Quantum
相关产品推荐
相关产品推荐

