使用Python从CSV文件创建嵌套字典时出现键值对覆盖问题
用Python从CSV生成嵌套字典的问题
问题背景
CSV文件结构如下:
| 列1 | 列2 | 列3 |
|---|---|---|
| A | flower | 12 |
| A | sun | 13 |
| B | cloud | 14 |
| B | water | 34 |
| C | rock | 12 |
期望生成的嵌套字典格式:
result_dict = { 'A': {'flower': 12, 'sun': 13}, 'B': {'cloud': 14, 'water': 34}, 'C': {'rock': 12} }
当前使用的代码:
import csv with open('file.csv', 'r') as csvFile: rows = csv.reader(csvFile) d = dict() for row in rows: head, tail = row[0], row[1:] d[head] = dict(zip(tail[0:], tail[1:])) print(d)
运行后不符合预期,每个外层键对应的内层字典只保留了最后一行的键值对,结果如下:
result_dict = { 'A': {'sun': 13}, 'B': {'water': 34}, 'C': {'rock': 12} }
问题原因
每次循环到同一外层键(比如'A')时,都会直接用d[head] = ...覆盖之前生成的内层字典,而非在原有字典中追加新的键值对。
解决方法
方法1:使用dict.setdefault
循环时先确保外层键对应的内层字典存在,再向内层字典添加键值对:
import csv with open('file.csv', 'r') as csvFile: rows = csv.reader(csvFile) d = dict() for row in rows: # 跳过表头(CSV无表头可删除此判断) if row[0] == '列1': continue head, inner_key, inner_value = row[0], row[1], int(row[2]) # 若head不存在于字典中,自动创建空字典作为对应值 d.setdefault(head, {})[inner_key] = inner_value print(d)
方法2:使用collections.defaultdict
通过defaultdict自动为不存在的外层键创建空字典,简化代码逻辑:
import csv from collections import defaultdict with open('file.csv', 'r') as csvFile: rows = csv.reader(csvFile) d = defaultdict(dict) for row in rows: # 跳过表头(CSV无表头可删除此判断) if row[0] == '列1': continue head, inner_key, inner_value = row[0], row[1], int(row[2]) d[head][inner_key] = inner_value # 如需转为普通字典,可使用dict(d) print(dict(d))
补充说明
- 若CSV文件没有表头,可删除代码中跳过表头的判断逻辑。
- 示例中把
row[2]转为int是因为原数据为数字,若CSV中对应列是字符串类型,可去掉int()转换。
内容的提问来源于stack exchange,提问作者Sarah
相关产品推荐
相关产品推荐

