如何将键无序的嵌套字典写入CSV?使用DictWriter遇类型错误
嵌套字典按指定顺序导出CSV的解决方案
问题场景
现有如下结构的嵌套字典,子字典内的键顺序混乱:
nested_dict = { 'dictA': {'key_1a': 'value_1a', 'key_2a': 'value2a',...}, 'dictB': {'key_2b': 'value_2b', 'key_1b': 'value_1b',...}, ... }
需要将其导出为格式固定的CSV文件,每行第一个元素为外层字典的键,后续为对应子字典按键排序后的值:
dictA, value_1a, value_2a,... dictB, value_1b, value_2b,... ...
使用DictWriter时触发错误:
return self.writer.writerows(map(self._dict_to_list, rowdicts)) TypeError: 'type' object is not iterable
错误原因
该错误大概率是因为向writerows()传入了错误参数——比如误传了dict类型而非可迭代的行数据列表,导致程序尝试迭代类型对象而非字典实例,从而抛出异常。
解决方案
方案一:手动排序+csv.writer直接写入
这种方式更贴合需求,无需适配DictWriter的键值对结构,直接按规则排序后写入:
import csv nested_dict = { 'dictA': {'key_1a': 'value_1a', 'key_2a': 'value2a'}, 'dictB': {'key_2b': 'value_2b', 'key_1b': 'value_1b'} } # 定义子字典键的排序规则:按key中的数字部分升序排列 def sort_inner_keys(keys): return sorted(keys, key=lambda x: int(x.split('_')[1])) with open('output.csv', 'w', newline='', encoding='utf-8') as csv_file: writer = csv.writer(csv_file) # 遍历外层字典,处理每一行数据 for outer_key, inner_dict in nested_dict.items(): # 对子字典的键排序,提取对应值 sorted_keys = sort_inner_keys(inner_dict.keys()) sorted_values = [inner_dict[key] for key in sorted_keys] # 写入一行:外层键 + 排序后的值 writer.writerow([outer_key] + sorted_values)
方案二:正确使用DictWriter(适合需要表头的场景)
如果需要保留CSV表头,可调整数据结构后使用DictWriter,核心是构造统一结构的行字典列表:
import csv nested_dict = { 'dictA': {'key_1a': 'value_1a', 'key_2a': 'value2a'}, 'dictB': {'key_2b': 'value_2b', 'key_1b': 'value_1b'} } rows = [] # 构造符合DictWriter要求的行字典 for outer_key, inner_dict in nested_dict.items(): # 对子字典键值对排序 sorted_items = sorted(inner_dict.items(), key=lambda x: int(x[0].split('_')[1])) sorted_values = [val for _, val in sorted_items] # 组装行字典:外层键为第一个字段,后续值按顺序命名为value1、value2... row_dict = {'外层键': outer_key} for idx, val in enumerate(sorted_values, 1): row_dict[f'值{idx}'] = val rows.append(row_dict) # 定义所有字段名 max_value_count = max(len(inner) for inner in nested_dict.values()) fieldnames = ['外层键'] + [f'值{idx}' for idx in range(1, max_value_count + 1)] with open('output_with_header.csv', 'w', newline='', encoding='utf-8') as csv_file: writer = csv.DictWriter(csv_file, fieldnames=fieldnames) # 写入表头(不需要可注释此行) writer.writeheader() # 写入所有行数据 writer.writerows(rows)
内容的提问来源于stack exchange,提问作者rtd730
相关产品推荐
相关产品推荐

