Python创建Medal命名元组列表时触发TypeError的问题排查
解决创建Medal命名元组时的TypeError问题
错误信息
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[19], line 1 ----> 1 medals =[Medal(line.split('\t')) for line in open('goldmedals.txt','r')] 2 medals[:10] Cell In[19], line 1, in <listcomp>(.0) ----> 1 medals =[Medal(line.split('\t')) for line in open('goldmedals.txt','r')] 2 medals[:10] TypeError: Medal.__new__() missing 3 required positional arguments: 'athlete', 'team', and 'event'
相关代码与数据
import collections import numpy as np open('goldmedals.txt','r').readlines()[:10]
文件前10行(制表符分隔):
["1992\tA Dijiang\tCHN\tBasketball Men's Basketball\tNA\t\t\t\t\t\t\t\t\t\t\t\t\n", "2012\tA Lamusi\tCHN\tJudo Men's Extra-Lightweight\tNA\t\t\t\t\t\t\t\t\t\t\t\t\n", "1920\tGunnar Nielsen Aaby\tDEN\tFootball Men's Football\tNA\t\t\t\t\t\t\t\t\t\t\t\t\n", "1900\tEdgar Lindenau Aabye\tDEN\tTug-Of-War Men's Tug-Of-War\tGold\t\t\t\t\t\t\t\t\t\t\t\t\n", "1988\tChristine Jacoba Aaftink\tNED\tSpeed Skating Women's 500 metres\tNA\t\t\t\t\t\t\t\t\t\t\t\t\n", "1988\tChristine Jacoba Aaftink\tNED\tSpeed Skating Women's 1,000 metres\tNA\t\t\t\t\t\t\t\t\t\t\t\t\n", "1992\tChristine Jacoba Aaftink\tNED\tSpeed Skating Women's 500 metres\tNA\t\t\t\t\t\t\t\t\t\t\t\t\n", "1992\tChristine Jacoba Aaftink\tNED\tSpeed Skating Women's 1,000 metres\tNA\t\t\t\t\t\t\t\t\t\t\t\t\n", "1994\tChristine Jacoba Aaftink\tNED\tSpeed Skating Women's 500 metres\tNA\t\t\t\t\t\t\t\t\t\t\t\t\n", "1994\tChristine Jacoba Aaftink\tNED\tSpeed Skating Women's 1,000 metres\tNA\t\t\t\t\t\t\t\t\t\t\t\t\n"]
Medal命名元组定义与测试
Medal = collections.namedtuple('Medal', ['year','athlete','team','event']) m = Medal('1992', 'A Dijiang', 'CHN', "Basketball Men's Basketball") m
测试结果:
Medal(year='1992', athlete='A Dijiang', team='CHN', event="Basketball Men's Basketball")
错误尝试
使用逗号分割创建列表(同样触发错误):
medals =[Medal(*line.split(',')) for line in open('goldmedals.txt','r')] medals[:10]
问题原因
- 未正确解包参数:原代码中
Medal(line.split('\t'))是把分割后的整个列表作为单个参数传给Medal,但Medal需要4个独立的位置参数,导致参数缺失。 - 多余字段干扰:文件每行按制表符分割后会得到多个元素(前4个是需要的字段,后面是NA或空值),直接全部传入会导致参数数量不匹配。
- 换行符残留:每行末尾的换行符会被包含在分割后的元素中,影响字段准确性。
解决方案
正确代码
# 方式1:列表推导式 medals = [Medal(*line.rstrip('\n').split('\t')[:4]) for line in open('goldmedals.txt','r')] # 方式2:更清晰的循环写法(推荐,便于调试) medals = [] with open('goldmedals.txt','r') as f: for line in f: # 去除末尾换行符 -> 按制表符分割 -> 取前4个有效字段 fields = line.rstrip('\n').split('\t')[:4] medals.append(Medal(*fields)) # 查看前10个结果 medals[:10]
关键说明
- 使用
*操作符解包分割后的列表,将列表中的每个元素作为独立参数传给Medal。 rstrip('\n')去除每行末尾的换行符,避免字段包含无效换行。[:4]只保留前4个有效字段,过滤掉后面多余的NA或空值,确保参数数量与Medal定义一致。
内容的提问来源于stack exchange,提问作者ian daniells
相关产品推荐
相关产品推荐

