You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python字符串拼接失败排查:姓名格式转换脚本中断

问题描述

需求是把“SURNAME, First Names, Religious Title”格式的姓名转换为“First Names Surname”格式。脚本能提取姓名组件,也能把全大写姓氏转成首字母大写,但在字符串拼接(join())环节后触发IndexError,脚本直接中断,输出空的person_cleaned列表。

代码片段

try:
  for x in range(0, df_length):
      print(df_length - x)
      e_df=df.iloc[[x]].fillna("@") # virtual value to avoid issues with empty data frames

      # CLEAN PERSON NAMES

      pers_name=e_df['pers_name'].values[0]
      print(pers_name)
      if "," in pers_name:
        pers_new=pers_name.split(",")
        first_name=pers_new[1].strip()
        print(first_name)
        last_name=pers_new[0].title().strip() # change "all caps" to sentence case
        print(last_name)
        rel_title=pers_new[2].strip()
        name_list=(first_name, last_name)

        try:
          name_reversed=" ".join(name_list) # religious titles are being ignored
          print("This is the new name: ", name_reversed)
        except Exception as e:
          print(e)
      else:
        name_reversed=re.sub("\s\s+" , " ", pers_name)
      print(name_reversed)
      person_cleaned.append(name_reversed)
    
except IndexError:
  print("No more names found.")

# add column with cleaned person names

print(person_cleaned)
print(len(person_cleaned))
df['pers_cleaned']=person_cleaned

frame_list.append(df)

输入数据示例

factoid_IDpers_IDpers_name...
5637OCRDORSCH, Anton Joseph...
5638OCRDORSCH, Anton Joseph...
2006OCRSCHEUICHAVIUS (Schevichavius), Gisbert, SJ...

输出结果

7155
 DORSCH, Anton Joseph
Anton Joseph
Dorsch
No more names found.
[]
问题分析与解决

错误根源

不是join()的问题,问题出在rel_title=pers_new[2].strip()这一行:

  • 第一个输入数据DORSCH, Anton Joseph用逗号分割后,得到的列表是['DORSCH', ' Anton Joseph'],只有2个元素,索引最大是1,直接访问索引2会触发IndexError。
  • 你把整个循环都包在了外层的try-except里,这个错误被捕获后直接跳出了整个循环,导致person_cleaned还没添加任何元素就终止了,所以输出空列表。

修复方案

1. 缩小异常捕获范围,避免一次错误中断全部处理

把外层包裹整个循环的try-except去掉,只在可能出错的地方单独处理,或者提前判断避免出错。

2. 提前判断分割后的列表长度,避免索引越界

在访问pers_new的索引前,先检查列表长度,确保存在对应元素再取值。

修改后的代码

person_cleaned = []
for x in range(df_length):
    print(df_length - x)
    e_df = df.iloc[[x]].fillna("@")
    pers_name = e_df['pers_name'].values[0]
    print(pers_name)
    if "," in pers_name:
        pers_new = pers_name.split(",")
        # 确保至少有姓氏和名字两部分才处理格式转换
        if len(pers_new) >= 2:
            first_name = pers_new[1].strip()
            print(first_name)
            last_name = pers_new[0].title().strip()
            print(last_name)
            # 只有存在第三部分时才提取宗教头衔(需求里不需要用到,可忽略)
            if len(pers_new) >= 3:
                rel_title = pers_new[2].strip()
            # 拼接名字,这里join完全没问题
            name_reversed = " ".join([first_name, last_name])
            print("This is the new name: ", name_reversed)
        else:
            # 处理格式不符合的情况,直接保留原姓名
            name_reversed = pers_name.strip()
    else:
        # 没有逗号的姓名,直接去重空格
        name_reversed = re.sub("\s\s+" , " ", pers_name)
    print(name_reversed)
    person_cleaned.append(name_reversed)

# 后续添加列的代码不变
print(person_cleaned)
print(len(person_cleaned))
df['pers_cleaned'] = person_cleaned
frame_list.append(df)

关键修改点

  • 移除了外层的try-except,避免单个数据出错导致整个处理中断
  • 增加了len(pers_new)的判断,确保访问索引前元素存在
  • 简化了名字拼接的写法,直接用列表传给join(),效果和元组一致
  • 明确处理了不同格式的姓名情况,避免异常

内容的提问来源于stack exchange,提问作者OnceUponATime

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 09:07:06