如何将特殊格式CSV文件转换为可筛选排序的字典?
问题
我有如下格式的CSV文件:首行为字段列表,其余行被双引号包裹。我希望将其转换为可进行后续筛选和排序的字典,使用Python的csv库编写了代码,但仅能转换2行,尝试拆分行也无效,csv库文档未解决问题,寻求解决方案。
CSV内容
id,name,surname,age "1, Johny, Black, 25" "2, Armando, White, 18" "3, Jack, Brown, ''" "4, Ronn, Davidson, ''" "5, Bill, Loney, 35"
我的代码
import csv dicts = list() with open("test.csv", "r", encoding="utf-8") as file: csv_reader = csv.reader(file) field_list = list() record_list = list() line_counter = 0 for row in csv_reader: if line_counter == 0: field_list = row line_counter += 1 else: records = row[0].split(',') record_list.append(records) counter = 0 full = dict() for record in record_list: for field in field_list: try: if field in full.keys(): full[field].append(record[counter]) counter += 1 else: full[field] = [record[counter]] if counter == len(record): break except Exception as e: pass print(full)
解决方案
问题根源
- 全局变量
counter未在每条记录处理前重置:处理完第一条记录后counter已达字段长度,后续记录直接触发break跳过处理。 - 手动用
split(',')拆分带引号的行:会导致字段前后残留空格,还无法正确处理示例中的''空值标记。 - 忽略了csv库原生功能:其实csv库可以直接解析被双引号包裹的整行内容,无需手动拆分。
推荐实现:用csv.DictReader
csv.DictReader能自动将每行转为字典,键对应首行字段名,代码简洁且避免手动处理的错误:
import csv # 存储每条记录的字典列表,方便后续筛选排序 result = [] with open("test.csv", "r", encoding="utf-8") as file: # 自动以首行作为字典的键 reader = csv.DictReader(file) for row in reader: # 清理字段:去除前后空格,把''替换为空字符串 cleaned_row = {key: value.strip().replace("''", "") for key, value in row.items()} # 把age字段转为整数(非空时) if cleaned_row['age']: cleaned_row['age'] = int(cleaned_row['age']) result.append(cleaned_row) # 输出结果 for item in result: print(item)
执行后得到的result是字典列表,每条记录对应一个字典,示例输出:
{'id': '1', 'name': 'Johny', 'surname': 'Black', 'age': 25} {'id': '2', 'name': 'Armando', 'surname': 'White', 'age': 18} {'id': '3', 'name': 'Jack', 'surname': 'Brown', 'age': ''} {'id': '4', 'name': 'Ronn', 'surname': 'Davidson', 'age': ''} {'id': '5', 'name': 'Bill', 'surname': 'Loney', 'age': 35}
修正原有代码的版本
如果要保留自己的实现逻辑,需重置counter并处理字段清理:
import csv with open("test.csv", "r", encoding="utf-8") as file: csv_reader = csv.reader(file) field_list = next(csv_reader) # 直接读取首行作为字段列表 record_list = [] for row in csv_reader: # 拆分后清理每个字段:去空格、替换''为空 records = [item.strip().replace("''", "") for item in row[0].split(',')] record_list.append(records) # 预先初始化每个字段的列表 full = {field: [] for field in field_list} for record in record_list: counter = 0 # 每条记录处理前重置计数器 for field in field_list: try: full[field].append(record[counter]) counter += 1 except Exception: full[field].append('') # 异常时补空值 # 可选:转换age字段为整数 for idx, age_str in enumerate(full['age']): if age_str: full['age'][idx] = int(age_str) print(full)
输出结果:
{'id': ['1', '2', '3', '4', '5'], 'name': ['Johny', 'Armando', 'Jack', 'Ronn', 'Bill'], 'surname': ['Black', 'White', 'Brown', 'Davidson', 'Loney'], 'age': [25, 18, '', '', 35]}
内容的提问来源于stack exchange,提问作者Gryver
相关产品推荐
相关产品推荐

